heroku-rails-saas 0.1.4 → 0.1.5
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.
- data/Gemfile.lock +1 -1
- data/README.md +15 -4
- data/heroku-rails.gemspec +1 -1
- data/lib/generators/templates/heroku.yml +9 -0
- data/lib/heroku-rails-saas/config.rb +20 -0
- data/lib/heroku-rails-saas/runner.rb +16 -0
- data/lib/heroku/rails/tasks.rb +34 -10
- data/spec/fixtures/awesomeapp.yml +9 -1
- data/spec/fixtures/heroku-config.yml +1 -1
- data/spec/fixtures/mediocreapp.yml +1 -1
- data/spec/heroku/rails/saas/heroku_config_spec.rb +32 -0
- metadata +8 -8
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -3,9 +3,8 @@ Heroku Rails SaaS | |
| 3 3 |  | 
| 4 4 | 
             
            Easier configuration and deployment of Rails apps on Heroku
         | 
| 5 5 |  | 
| 6 | 
            -
            Configure all your Heroku  | 
| 7 | 
            -
            Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, and 
         | 
| 8 | 
            -
            environment variables for awesomeapp.
         | 
| 6 | 
            +
            Configure all your Heroku environments via a YML file (config/heroku.yml) that defines all your environments, addons, scaling settings and environment variables.
         | 
| 7 | 
            +
            Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, scaling settings and environment variables for awesomeapp.
         | 
| 9 8 |  | 
| 10 9 | 
             
            ## Install
         | 
| 11 10 |  | 
| @@ -44,6 +43,10 @@ For all configuration settings | |
| 44 43 | 
             
                  - scheduler:standard
         | 
| 45 44 | 
             
                  # add any other addons here
         | 
| 46 45 |  | 
| 46 | 
            +
                scale:
         | 
| 47 | 
            +
                  web: 1
         | 
| 48 | 
            +
                  worker: 0
         | 
| 49 | 
            +
             | 
| 47 50 | 
             
            For an app specific settings awesomeapp
         | 
| 48 51 |  | 
| 49 52 | 
             
                apps:
         | 
| @@ -70,6 +73,13 @@ For an app specific settings awesomeapp | |
| 70 73 | 
             
                  - cron:daily
         | 
| 71 74 | 
             
                  - newrelic:bronze
         | 
| 72 75 |  | 
| 76 | 
            +
                scale:
         | 
| 77 | 
            +
                  production:
         | 
| 78 | 
            +
                    web: 3
         | 
| 79 | 
            +
                    worker: 2
         | 
| 80 | 
            +
                  staging:
         | 
| 81 | 
            +
                    web: 2
         | 
| 82 | 
            +
                    worker: 1
         | 
| 73 83 |  | 
| 74 84 | 
             
            ### Setting up Heroku
         | 
| 75 85 |  | 
| @@ -99,7 +109,7 @@ A special rake task 'all' is created that causes any further commands to | |
| 99 109 | 
             
            execute on all heroku apps (Note: Any environment labeled `production` will not
         | 
| 100 110 | 
             
            be included, you must explicitly state it).
         | 
| 101 111 |  | 
| 102 | 
            -
             | 
| 112 | 
            +
            Furthermore there are rake task 'environments' created from environments in configs
         | 
| 103 113 | 
             
            that causes any further commands to execute on all heroku apps.
         | 
| 104 114 |  | 
| 105 115 | 
             
                rake all:production heroku:info
         | 
| @@ -120,6 +130,7 @@ A full list of tasks provided: | |
| 120 130 | 
             
                rake heroku:remotes             # Add git remotes for all apps in this project
         | 
| 121 131 | 
             
                rake heroku:migrate             # Migrates and restarts remote servers
         | 
| 122 132 | 
             
                rake heroku:restart             # Restarts remote servers
         | 
| 133 | 
            +
                rake heroku:scale               # Scales heroku processes
         | 
| 123 134 |  | 
| 124 135 | 
             
                rake heroku:setup               # runs all heroku setup scripts
         | 
| 125 136 | 
             
                rake heroku:setup:addons        # sets up the heroku addons
         | 
    
        data/heroku-rails.gemspec
    CHANGED
    
    
| @@ -33,6 +33,11 @@ | |
| 33 33 | 
             
            #   - cron:daily
         | 
| 34 34 | 
             
            #   - newrelic:bronze
         | 
| 35 35 |  | 
| 36 | 
            +
            # scale:
         | 
| 37 | 
            +
            #   production:
         | 
| 38 | 
            +
            #     web: 2
         | 
| 39 | 
            +
            #     worker: 1
         | 
| 40 | 
            +
             | 
| 36 41 |  | 
| 37 42 | 
             
            # The following are configuration settings formally under the :all key
         | 
| 38 43 | 
             
            # for all apps and thier environments
         | 
| @@ -50,3 +55,7 @@ collaborators: | |
| 50 55 | 
             
            addons:
         | 
| 51 56 | 
             
              - scheduler:standard
         | 
| 52 57 | 
             
              # add any other addons here
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            scale:
         | 
| 60 | 
            +
              web: 1
         | 
| 61 | 
            +
              worker: 0
         | 
| @@ -22,6 +22,12 @@ module HerokuRailsSaas | |
| 22 22 | 
             
                    name, env = app_env.split(SEPERATOR)
         | 
| 23 23 | 
             
                    env
         | 
| 24 24 | 
             
                  end
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                  def extract_name_from(app_env)
         | 
| 27 | 
            +
                    name, env = app_env.split(SEPERATOR)
         | 
| 28 | 
            +
                    name
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                  
         | 
| 25 31 | 
             
                end
         | 
| 26 32 |  | 
| 27 33 | 
             
                attr_accessor :settings
         | 
| @@ -89,6 +95,20 @@ module HerokuRailsSaas | |
| 89 95 | 
             
                  all.merge(merged_environment_configs)
         | 
| 90 96 | 
             
                end
         | 
| 91 97 |  | 
| 98 | 
            +
                # pull out the scaling setting hash for a particular app environment
         | 
| 99 | 
            +
                def scale(app_env)
         | 
| 100 | 
            +
                  name, env = app_env.split(SEPERATOR)
         | 
| 101 | 
            +
                  scaling = self.settings['scale'] || {}
         | 
| 102 | 
            +
                  all = scaling['all'] || {}
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  app_scaling = (scaling[name] && scaling[name].reject { |k,v| v.class == Hash }) || {}
         | 
| 105 | 
            +
                  # overwrite app scaling with the environment specific ones
         | 
| 106 | 
            +
                  merged_environment_scaling = app_scaling.merge((scaling[name] && scaling[name][env]) || {})
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  # overwrite all scaling with the environment specific ones
         | 
| 109 | 
            +
                  all.merge(merged_environment_scaling)
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 92 112 | 
             
                # return a list of domains for a particular app environment
         | 
| 93 113 | 
             
                def domains(app_env)
         | 
| 94 114 | 
             
                  name, env = app_env.split(SEPERATOR)
         | 
| @@ -204,6 +204,22 @@ module HerokuRailsSaas | |
| 204 204 | 
             
                  end
         | 
| 205 205 | 
             
                end
         | 
| 206 206 |  | 
| 207 | 
            +
                def scale
         | 
| 208 | 
            +
                  authorize unless @heroku
         | 
| 209 | 
            +
                  each_heroku_app do |heroku_env, app_name, repo|
         | 
| 210 | 
            +
                    scaling = @config.scale(heroku_env)
         | 
| 211 | 
            +
                    scaling.each do |process_name, instance_count|
         | 
| 212 | 
            +
                      begin
         | 
| 213 | 
            +
                        puts "Scaling app #{app_name} process #{process_name} to #{instance_count}"
         | 
| 214 | 
            +
                        response = @heroku.ps_scale(app_name, {:type => process_name, :qty => instance_count })
         | 
| 215 | 
            +
                        puts "Response: #{response}"
         | 
| 216 | 
            +
                      rescue => e
         | 
| 217 | 
            +
                        puts "Failed to scale #{app_name}. Error: #{e.inspect}"
         | 
| 218 | 
            +
                      end
         | 
| 219 | 
            +
                    end
         | 
| 220 | 
            +
                  end
         | 
| 221 | 
            +
                end
         | 
| 222 | 
            +
             | 
| 207 223 | 
             
                # cycles through each configured heroku app
         | 
| 208 224 | 
             
                # yields the environment name, the app name, and the repo url
         | 
| 209 225 | 
             
                def each_heroku_app
         | 
    
        data/lib/heroku/rails/tasks.rb
    CHANGED
    
    | @@ -141,13 +141,6 @@ namespace :heroku do | |
| 141 141 | 
             
              task :switch_environment do
         | 
| 142 142 | 
             
              end
         | 
| 143 143 |  | 
| 144 | 
            -
              desc "Force deploys, migrates and restarts latest code"
         | 
| 145 | 
            -
              task :force_deploy do
         | 
| 146 | 
            -
                @git_push_arguments ||= []
         | 
| 147 | 
            -
                @git_push_arguments << '--force'
         | 
| 148 | 
            -
                Rake::Task["heroku:deploy"].execute
         | 
| 149 | 
            -
              end
         | 
| 150 | 
            -
             | 
| 151 144 | 
             
              desc "Captures a bundle on Heroku"
         | 
| 152 145 | 
             
              task :capture do
         | 
| 153 146 | 
             
                HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
         | 
| @@ -177,6 +170,11 @@ namespace :heroku do | |
| 177 170 | 
             
                end
         | 
| 178 171 | 
             
              end
         | 
| 179 172 |  | 
| 173 | 
            +
              desc "Scales heroku processes"
         | 
| 174 | 
            +
              task :scale do
         | 
| 175 | 
            +
                HEROKU_RUNNER.scale
         | 
| 176 | 
            +
              end
         | 
| 177 | 
            +
             | 
| 180 178 | 
             
              namespace :setup do
         | 
| 181 179 |  | 
| 182 180 | 
             
                desc "Creates the apps on Heroku"
         | 
| @@ -232,11 +230,11 @@ namespace :heroku do | |
| 232 230 | 
             
                desc "Pulls the database from heroku and stores it into db/dumps/"
         | 
| 233 231 | 
             
                task :pull do
         | 
| 234 232 | 
             
                  HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
         | 
| 235 | 
            -
                    system_with_echo "heroku  | 
| 236 | 
            -
                    dump = `heroku  | 
| 233 | 
            +
                    system_with_echo "heroku pgbackups:capture --app #{app_name}"
         | 
| 234 | 
            +
                    dump = `heroku pgbackups --app #{app_name}`.split("\n").last.split(" ").first
         | 
| 237 235 | 
             
                    system_with_echo "mkdir -p #{HerokuRailsSaas::Config.root}/db/dumps"
         | 
| 238 236 | 
             
                    file = "#{HerokuRailsSaas::Config.root}/db/dumps/#{dump}.sql.gz"
         | 
| 239 | 
            -
                    url = `heroku  | 
| 237 | 
            +
                    url = `heroku pgbackups:url --app #{app_name} #{dump}`.chomp
         | 
| 240 238 | 
             
                    system_with_echo "wget", url, "-O", file
         | 
| 241 239 |  | 
| 242 240 | 
             
                    # TODO: these are a bit distructive...
         | 
| @@ -245,5 +243,31 @@ namespace :heroku do | |
| 245 243 | 
             
                    # system_with_echo "rake jobs:clear"
         | 
| 246 244 | 
             
                  end
         | 
| 247 245 | 
             
                end
         | 
| 246 | 
            +
                
         | 
| 247 | 
            +
                desc "Resets a Non Production database"
         | 
| 248 | 
            +
                task :reset do
         | 
| 249 | 
            +
                  HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
         | 
| 250 | 
            +
                    unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
         | 
| 251 | 
            +
                      system_with_echo "heroku pg:reset DATABASE_URL --app #{app_name} --confirm #{app_name}"
         | 
| 252 | 
            +
                    else
         | 
| 253 | 
            +
                      puts "Will not reset the Production database"
         | 
| 254 | 
            +
                    end
         | 
| 255 | 
            +
                  end
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
                
         | 
| 258 | 
            +
                desc "Copies a database over a Non Production database"
         | 
| 259 | 
            +
                task :copy,[ :source]  => :reset do |t, args|
         | 
| 260 | 
            +
                  HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
         | 
| 261 | 
            +
                    raise "missing source" unless HEROKU_CONFIG.app_name_on_heroku(args.source)
         | 
| 262 | 
            +
                      
         | 
| 263 | 
            +
                    unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
         | 
| 264 | 
            +
                      source_app_name = HEROKU_CONFIG.app_name_on_heroku(args.source)
         | 
| 265 | 
            +
                      system_with_echo "heroku pgbackups:restore DATABASE_URL `heroku pgbackups:url --app #{source_app_name}` --app #{app_name} --confirm #{app_name}"
         | 
| 266 | 
            +
                    else
         | 
| 267 | 
            +
                      puts "Will not overwrite the Production database"
         | 
| 268 | 
            +
                    end
         | 
| 269 | 
            +
                  end
         | 
| 270 | 
            +
                end
         | 
| 271 | 
            +
             | 
| 248 272 | 
             
              end
         | 
| 249 273 | 
             
            end
         | 
| @@ -153,5 +153,37 @@ module HerokuRailsSaas | |
| 153 153 | 
             
                  end
         | 
| 154 154 | 
             
                end
         | 
| 155 155 |  | 
| 156 | 
            +
                describe "#scale" do
         | 
| 157 | 
            +
                  context "mediocrapp" do
         | 
| 158 | 
            +
                    it "should include the scaling settings defined in 'all'" do
         | 
| 159 | 
            +
                      @scale = @config.scale('mediocreapp')
         | 
| 160 | 
            +
                      @scale['web'].should_not be_nil
         | 
| 161 | 
            +
                      @scale['worker'].should_not be_nil
         | 
| 162 | 
            +
                      @scale['web'].should eql 1
         | 
| 163 | 
            +
                      @scale['worker'].should eql 0
         | 
| 164 | 
            +
                    end
         | 
| 165 | 
            +
                  end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  context "staging environment" do
         | 
| 168 | 
            +
                    it "should include the scaling settings defined in 'staging'" do
         | 
| 169 | 
            +
                      @scale = @config.scale('awesomeapp:staging')
         | 
| 170 | 
            +
                      @scale['web'].should_not be_nil
         | 
| 171 | 
            +
                      @scale['worker'].should_not be_nil
         | 
| 172 | 
            +
                      @scale['web'].should eql 2
         | 
| 173 | 
            +
                      @scale['worker'].should eql 1
         | 
| 174 | 
            +
                    end
         | 
| 175 | 
            +
                  end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  context "production environment" do
         | 
| 178 | 
            +
                    it "should include the scaling settings defined in 'production'" do
         | 
| 179 | 
            +
                      @scale = @config.scale('awesomeapp:production')
         | 
| 180 | 
            +
                      @scale['web'].should_not be_nil
         | 
| 181 | 
            +
                      @scale['worker'].should_not be_nil
         | 
| 182 | 
            +
                      @scale['web'].should eql 3
         | 
| 183 | 
            +
                      @scale['worker'].should eql 2
         | 
| 184 | 
            +
                    end
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
             | 
| 156 188 | 
             
              end
         | 
| 157 189 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: heroku-rails-saas
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.5
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -12,11 +12,11 @@ authors: | |
| 12 12 | 
             
            autorequire: 
         | 
| 13 13 | 
             
            bindir: bin
         | 
| 14 14 | 
             
            cert_chain: []
         | 
| 15 | 
            -
            date: 2012-05- | 
| 15 | 
            +
            date: 2012-05-04 00:00:00.000000000Z
         | 
| 16 16 | 
             
            dependencies:
         | 
| 17 17 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 18 18 | 
             
              name: heroku
         | 
| 19 | 
            -
              requirement: & | 
| 19 | 
            +
              requirement: &2156355220 !ruby/object:Gem::Requirement
         | 
| 20 20 | 
             
                none: false
         | 
| 21 21 | 
             
                requirements:
         | 
| 22 22 | 
             
                - - ! '>='
         | 
| @@ -24,10 +24,10 @@ dependencies: | |
| 24 24 | 
             
                    version: 2.24.1
         | 
| 25 25 | 
             
              type: :runtime
         | 
| 26 26 | 
             
              prerelease: false
         | 
| 27 | 
            -
              version_requirements: * | 
| 27 | 
            +
              version_requirements: *2156355220
         | 
| 28 28 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 29 29 | 
             
              name: rspec
         | 
| 30 | 
            -
              requirement: & | 
| 30 | 
            +
              requirement: &2156354200 !ruby/object:Gem::Requirement
         | 
| 31 31 | 
             
                none: false
         | 
| 32 32 | 
             
                requirements:
         | 
| 33 33 | 
             
                - - ~>
         | 
| @@ -35,7 +35,7 @@ dependencies: | |
| 35 35 | 
             
                    version: '2.0'
         | 
| 36 36 | 
             
              type: :development
         | 
| 37 37 | 
             
              prerelease: false
         | 
| 38 | 
            -
              version_requirements: * | 
| 38 | 
            +
              version_requirements: *2156354200
         | 
| 39 39 | 
             
            description: Manage multiple Heroku instances/apps for a single Rails app using Rake.
         | 
| 40 40 | 
             
            email: lance.sanchez@gmail.com
         | 
| 41 41 | 
             
            executables: []
         | 
| @@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 84 84 | 
             
                  version: '0'
         | 
| 85 85 | 
             
                  segments:
         | 
| 86 86 | 
             
                  - 0
         | 
| 87 | 
            -
                  hash:  | 
| 87 | 
            +
                  hash: 3808687770431151887
         | 
| 88 88 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 89 89 | 
             
              none: false
         | 
| 90 90 | 
             
              requirements:
         | 
| @@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 93 93 | 
             
                  version: '0'
         | 
| 94 94 | 
             
                  segments:
         | 
| 95 95 | 
             
                  - 0
         | 
| 96 | 
            -
                  hash:  | 
| 96 | 
            +
                  hash: 3808687770431151887
         | 
| 97 97 | 
             
            requirements: []
         | 
| 98 98 | 
             
            rubyforge_project: none
         | 
| 99 99 | 
             
            rubygems_version: 1.8.6
         |