takeoff 0.0.1
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 +14 -0
 - data/Gemfile +3 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +268 -0
 - data/Rakefile +1 -0
 - data/bin/takeoff +6 -0
 - data/example.Launchfile +86 -0
 - data/lib/takeoff/cli.rb +46 -0
 - data/lib/takeoff/configuration.rb +58 -0
 - data/lib/takeoff/ext/middleware_builder.rb +54 -0
 - data/lib/takeoff/helpers.rb +44 -0
 - data/lib/takeoff/plan/base.rb +62 -0
 - data/lib/takeoff/plan/default.rb +36 -0
 - data/lib/takeoff/plan/heroku.rb +41 -0
 - data/lib/takeoff/stage/base.rb +17 -0
 - data/lib/takeoff/stage/checkout_development_branch.rb +24 -0
 - data/lib/takeoff/stage/heroku/disable_preboot.rb +37 -0
 - data/lib/takeoff/stage/heroku/enable_maintenance_mode.rb +27 -0
 - data/lib/takeoff/stage/heroku/migrate_database.rb +52 -0
 - data/lib/takeoff/stage/heroku/precompile_and_sync_assets.rb +45 -0
 - data/lib/takeoff/stage/heroku/push_to_server.rb +16 -0
 - data/lib/takeoff/stage/heroku/remember_commits.rb +19 -0
 - data/lib/takeoff/stage/heroku/scale_down_workers.rb +33 -0
 - data/lib/takeoff/stage/heroku/verify_server_not_already_up_to_date.rb +17 -0
 - data/lib/takeoff/stage/heroku/verify_staging_up_to_date.rb +28 -0
 - data/lib/takeoff/stage/log.rb +28 -0
 - data/lib/takeoff/stage/look_out_for_danger.rb +15 -0
 - data/lib/takeoff/stage/point_checkpoint_to_development.rb +22 -0
 - data/lib/takeoff/stage/push_to_github.rb +14 -0
 - data/lib/takeoff/stage/stash_changes.rb +31 -0
 - data/lib/takeoff/stage/verify_circle_ci_status.rb +46 -0
 - data/lib/takeoff/stage/verify_github_up_to_date.rb +18 -0
 - data/lib/takeoff/version.rb +3 -0
 - data/lib/takeoff.rb +44 -0
 - data/takeoff.gemspec +23 -0
 - metadata +152 -0
 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/plan/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "takeoff/stage/log"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "takeoff/stage/look_out_for_danger"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "takeoff/stage/stash_changes"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "takeoff/stage/checkout_development_branch"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "takeoff/stage/verify_github_up_to_date"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "takeoff/stage/point_checkpoint_to_development"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "takeoff/stage/push_to_github"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 12 
     | 
    
         
            +
              module Plan
         
     | 
| 
      
 13 
     | 
    
         
            +
                class Default < Base
         
     | 
| 
      
 14 
     | 
    
         
            +
                  env.merge!(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    environment:        "production",
         
     | 
| 
      
 16 
     | 
    
         
            +
                    github_remote:      "github",
         
     | 
| 
      
 17 
     | 
    
         
            +
                    development_branch: "develop",
         
     | 
| 
      
 18 
     | 
    
         
            +
                    checkpoint_branch:  "master"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  )
         
     | 
| 
      
 20 
     | 
    
         
            +
                  
         
     | 
| 
      
 21 
     | 
    
         
            +
                  stages do
         
     | 
| 
      
 22 
     | 
    
         
            +
                    use Stage::Log
         
     | 
| 
      
 23 
     | 
    
         
            +
                    use Stage::LookOutForDanger
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    use Stage::StashChanges
         
     | 
| 
      
 26 
     | 
    
         
            +
                    use Stage::CheckoutDevelopmentBranch
         
     | 
| 
      
 27 
     | 
    
         
            +
                    
         
     | 
| 
      
 28 
     | 
    
         
            +
                    use Stage::VerifyGithubUpToDate
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    use Stage::PointCheckpointToDevelopment
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    use Stage::PushToGithub
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/plan/default"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "takeoff/stage/heroku/remember_commits"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "takeoff/stage/heroku/verify_server_not_already_up_to_date"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "takeoff/stage/heroku/disable_preboot"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "takeoff/stage/heroku/scale_down_workers"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "takeoff/stage/heroku/enable_maintenance_mode"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "takeoff/stage/heroku/push_to_server"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "takeoff/stage/heroku/migrate_database"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 12 
     | 
    
         
            +
              module Plan
         
     | 
| 
      
 13 
     | 
    
         
            +
                class Heroku < Default
         
     | 
| 
      
 14 
     | 
    
         
            +
                  env.merge!(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    server_remote: "heroku"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  )
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  stages do
         
     | 
| 
      
 19 
     | 
    
         
            +
                    insert_after Stage::Log,
         
     | 
| 
      
 20 
     | 
    
         
            +
                      Stage::Heroku::RememberCommits
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    insert_after Stage::VerifyGithubUpToDate, 
         
     | 
| 
      
 23 
     | 
    
         
            +
                      Stage::Heroku::VerifyServerNotAlreadyUpToDate
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    insert_after Stage::PointCheckpointToDevelopment, [
         
     | 
| 
      
 26 
     | 
    
         
            +
                      Stage::Heroku::DisablePreboot,
         
     | 
| 
      
 27 
     | 
    
         
            +
                      Stage::Heroku::ScaleDownWorkers,
         
     | 
| 
      
 28 
     | 
    
         
            +
                      Stage::Heroku::EnableMaintenanceMode,
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                      Stage::Heroku::PushToServer,
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      Stage::Heroku::MigrateDatabase
         
     | 
| 
      
 33 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            Takeoff.configure do
         
     | 
| 
      
 40 
     | 
    
         
            +
              plan :heroku, Takeoff::Plan::Heroku
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class CheckoutDevelopmentBranch < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    previous_branch = `git rev-parse --abbrev-ref HEAD`.strip
         
     | 
| 
      
 8 
     | 
    
         
            +
                    previous_branch = `git rev-parse --verify HEAD`.strip if previous_branch == "HEAD"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    return @app.call(env) if previous_branch == env[:development_branch]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    log     "Checking out development branch"
         
     | 
| 
      
 13 
     | 
    
         
            +
                    execute "git checkout #{env[:development_branch]}"
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 16 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 18 
     | 
    
         
            +
                      log     "Checking out original branch '#{previous_branch}'"
         
     | 
| 
      
 19 
     | 
    
         
            +
                      execute "git checkout #{previous_branch}"
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class DisablePreboot < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def run?(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      features = `heroku features --remote #{env[:server_remote]}`
         
     | 
| 
      
 9 
     | 
    
         
            +
                      preboot_line = features.split("\n").find { |feature| feature =~ /\A\[[+ ]\] preboot/ }
         
     | 
| 
      
 10 
     | 
    
         
            +
                      preboot_enabled = preboot_line.start_with?("[+]")
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      preboot_enabled
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 16 
     | 
    
         
            +
                      unless env[:dangerous]
         
     | 
| 
      
 17 
     | 
    
         
            +
                        log "Skipping disabling preboot because nothing dangerous is going on"
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                        return @app.call(env) 
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      return @app.call(env) unless run?(env)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      log     "Disabling preboot"
         
     | 
| 
      
 25 
     | 
    
         
            +
                      execute "heroku features:disable preboot --remote #{env[:server_remote]}"
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 28 
     | 
    
         
            +
                        @app.call(env)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 30 
     | 
    
         
            +
                        log     "Enabling preboot"
         
     | 
| 
      
 31 
     | 
    
         
            +
                        execute "heroku features:enable preboot --remote #{env[:server_remote]}"
         
     | 
| 
      
 32 
     | 
    
         
            +
                      end
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class EnableMaintenanceMode < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      unless env[:dangerous]
         
     | 
| 
      
 9 
     | 
    
         
            +
                        log "Skipping maintenance mode because nothing dangerous is going on"
         
     | 
| 
      
 10 
     | 
    
         
            +
                        
         
     | 
| 
      
 11 
     | 
    
         
            +
                        return @app.call(env) 
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      log     "Enabling maintenance mode"
         
     | 
| 
      
 15 
     | 
    
         
            +
                      execute "heroku maintenance:on --remote #{env[:server_remote]}"
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 18 
     | 
    
         
            +
                        @app.call(env)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 20 
     | 
    
         
            +
                        log     "Disabling maintenance mode"
         
     | 
| 
      
 21 
     | 
    
         
            +
                        execute "heroku maintenance:off --remote #{env[:server_remote]}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class MigrateDatabase < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def self.dangerous?(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      new(nil).dangerous?(env)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    def dangerous?(env)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      return @dangerous if defined?(@dangerous)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      return @dangerous = false unless run?(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      diff = diff(env[:deployed_commit], env[:new_commit], ["db/migrate"])
         
     | 
| 
      
 17 
     | 
    
         
            +
                      
         
     | 
| 
      
 18 
     | 
    
         
            +
                      unsafe_active_record_terms  = /change_column|change_table|drop_table|remove_column|remove_index|rename_column|execute/
         
     | 
| 
      
 19 
     | 
    
         
            +
                      unsafe_mongoid_terms        = /renameCollection|\.drop|$rename|$set|$unset|indexes\.create|indexes\.drop/
         
     | 
| 
      
 20 
     | 
    
         
            +
                      unsafe_terms = Regexp.union(unsafe_active_record_terms, unsafe_mongoid_terms)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      @dangerous = diff.split("\n").any? do |line|
         
     | 
| 
      
 23 
     | 
    
         
            +
                        line =~ unsafe_terms && line !~ /#\s*safe/i
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    def run?(env)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      files_have_changed?(env[:deployed_commit], env[:new_commit], ["db/migrate"])
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    
         
     | 
| 
      
 31 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 32 
     | 
    
         
            +
                      unless run?(env)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        log "Skipping database migrations"
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                        return @app.call(env) 
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      log     "Running database migrations"
         
     | 
| 
      
 39 
     | 
    
         
            +
                      execute "heroku run rake db:migrate --remote #{env[:server_remote]}"
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                      # If ActiveRecord needs to rebuild its column name cache, restart the app.
         
     | 
| 
      
 42 
     | 
    
         
            +
                      if dangerous?(env)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        log     "Restarting application"
         
     | 
| 
      
 44 
     | 
    
         
            +
                        execute "heroku restart --remote #{env[:server_remote]}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class PrecompileAndSyncAssets < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def run?(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      files = %w(app/assets lib/assets vendor/asset Gemfile.lock config/initializers/assets.rb)
         
     | 
| 
      
 9 
     | 
    
         
            +
                      files_have_changed?(env[:deployed_commit], env[:new_commit], files)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      unless run?(env)
         
     | 
| 
      
 14 
     | 
    
         
            +
                        log "Skipping precompilation of assets"
         
     | 
| 
      
 15 
     | 
    
         
            +
                        
         
     | 
| 
      
 16 
     | 
    
         
            +
                        return @app.call(env)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 20 
     | 
    
         
            +
                        log     "Precompiling assets"
         
     | 
| 
      
 21 
     | 
    
         
            +
                        execute "RAILS_ENV=#{env[:environment]} bundle exec rake assets:precompile"
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                        log     "Syncing assets"
         
     | 
| 
      
 24 
     | 
    
         
            +
                        execute "RAILS_ENV=#{env[:environment]} bundle exec rake assets:sync"
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                        if file_has_changed_locally?("public/assets/manifest-#{env[:environment]}.json")
         
     | 
| 
      
 27 
     | 
    
         
            +
                          log     "Committing updated asset manifests"
         
     | 
| 
      
 28 
     | 
    
         
            +
                          execute "git add public/assets/manifest-#{env[:environment]}.json"            
         
     | 
| 
      
 29 
     | 
    
         
            +
                          execute "git commit -m 'Update asset manifest for #{env[:environment]}.' -m '[ci skip]'"
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                          log     "Pushing development branch to GitHub"
         
     | 
| 
      
 32 
     | 
    
         
            +
                          execute "git push github #{env[:development_branch]}:#{env[:development_branch]} --force"
         
     | 
| 
      
 33 
     | 
    
         
            +
                        end
         
     | 
| 
      
 34 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 35 
     | 
    
         
            +
                        log     "Deleting precompiled assets"
         
     | 
| 
      
 36 
     | 
    
         
            +
                        execute "git ls-files -o --exclude-standard public/assets | xargs rm"
         
     | 
| 
      
 37 
     | 
    
         
            +
                        # We can't use `rm -r ./public/assets` because we still need the manifest files.
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class PushToServer < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      log     "Pushing to server"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      execute "git push #{env[:server_remote]} #{env[:checkpoint_branch]}:master --force"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class RememberCommits < Base      
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      log     "Fetching from server"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      execute "git fetch #{env[:server_remote]}"
         
     | 
| 
      
 10 
     | 
    
         
            +
                      
         
     | 
| 
      
 11 
     | 
    
         
            +
                      env[:deployed_commit] = latest_commit("#{env[:server_remote]}/master")
         
     | 
| 
      
 12 
     | 
    
         
            +
                      env[:new_commit]      = latest_commit(env[:development_branch])
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class ScaleDownWorkers < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      unless env[:dangerous]
         
     | 
| 
      
 9 
     | 
    
         
            +
                        log "Skipping scaling down workers because nothing dangerous is going on"
         
     | 
| 
      
 10 
     | 
    
         
            +
                        
         
     | 
| 
      
 11 
     | 
    
         
            +
                        return @app.call(env) 
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
                      
         
     | 
| 
      
 14 
     | 
    
         
            +
                      number_of_workers = execute(
         
     | 
| 
      
 15 
     | 
    
         
            +
                        "heroku ps --remote #{env[:server_remote]} | grep '^worker.' | wc -l | tr -d ' '"
         
     | 
| 
      
 16 
     | 
    
         
            +
                      ).to_i
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      return @app.call(env) if number_of_workers == 0
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      log     "Scaling down workers"
         
     | 
| 
      
 21 
     | 
    
         
            +
                      execute "heroku scale worker=0 --remote #{env[:server_remote]}"
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 24 
     | 
    
         
            +
                        @app.call(env)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 26 
     | 
    
         
            +
                        log     "Scaling up workers"
         
     | 
| 
      
 27 
     | 
    
         
            +
                        execute "heroku scale worker=#{number_of_workers || 0} --remote #{env[:server_remote]}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                      end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class VerifyServerNotAlreadyUpToDate < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      if env[:deployed_commit] == env[:new_commit]
         
     | 
| 
      
 9 
     | 
    
         
            +
                        raise "The server is already up to date."
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Heroku
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class VerifyStagingUpToDate < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def call(env)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      unless Takeoff.plan?("staging")
         
     | 
| 
      
 9 
     | 
    
         
            +
                        log "WARNING: Skipping verification that the staging server is up to date because a launch plan for the staging environment has not been set up"
         
     | 
| 
      
 10 
     | 
    
         
            +
                        
         
     | 
| 
      
 11 
     | 
    
         
            +
                        return @app.call(env)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      staging_takeoff = Takeoff[:staging]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      log     "Fetching from staging server"
         
     | 
| 
      
 17 
     | 
    
         
            +
                      execute "git fetch #{staging_takeoff.env[:server_remote]}"
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      unless branches_up_to_date?("#{staging_takeoff.env[:server_remote]}/master", env[:development_branch])
         
     | 
| 
      
 20 
     | 
    
         
            +
                        raise "The staging server is not up to date with branch '#{env[:development_branch]}'. Deploy to staging first."
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Log < Base      
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    log "Ready for takeoff! Deploying to #{env[:environment]} server..."
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    start_time = Time.now
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 12 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end_time = Time.now
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      log "Deploying failed in #{end_time - start_time} seconds. Takeoff unsuccessful."
         
     | 
| 
      
 17 
     | 
    
         
            +
                      puts
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      raise
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end_time = Time.now
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      log "Deploying finished in #{end_time - start_time} seconds. Takeoff successful."
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class LookOutForDanger < Base      
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    env[:stages]            = env[:plan].stages.middlewares
         
     | 
| 
      
 8 
     | 
    
         
            +
                    env[:dangerous_stages]  = env[:stages].select { |stage| stage.respond_to?(:dangerous?) && stage.dangerous?(env) }
         
     | 
| 
      
 9 
     | 
    
         
            +
                    env[:dangerous]         = env[:dangerous_stages].count > 0
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class PointCheckpointToDevelopment < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    return @app.call(env) if env[:development_branch] == env[:checkpoint_branch]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    log     "Pointing checkpoint branch to development branch"
         
     | 
| 
      
 10 
     | 
    
         
            +
                    execute "git checkout #{env[:checkpoint_branch]}"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 13 
     | 
    
         
            +
                      execute "git reset --hard #{env[:development_branch]}"
         
     | 
| 
      
 14 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 15 
     | 
    
         
            +
                      execute "git checkout #{env[:development_branch]}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class PushToGithub < Base      
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    log     "Pushing checkpoint branch to GitHub"
         
     | 
| 
      
 8 
     | 
    
         
            +
                    execute "git push github #{env[:checkpoint_branch]}:#{env[:checkpoint_branch]} --force"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class StashChanges < Base      
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    status = `git status --untracked-files --short`
         
     | 
| 
      
 8 
     | 
    
         
            +
                    return @app.call(env) if status.blank?
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    stash_name = "Takeoff Auto-Stash: #{Time.now}"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    log     "Stashing uncommitted changes"
         
     | 
| 
      
 13 
     | 
    
         
            +
                    execute "git stash save -u #{Shellwords.escape(stash_name)}"
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 16 
     | 
    
         
            +
                      @app.call(env)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 18 
     | 
    
         
            +
                      log "Applying previously stashed uncommitted changes"
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      stashes       = `git stash list`
         
     | 
| 
      
 21 
     | 
    
         
            +
                      matched_stash = stashes.split("\n").find { |stash| stash.include?(stash_name) }
         
     | 
| 
      
 22 
     | 
    
         
            +
                      label         = matched_stash.match(/^([^:]+)/)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      execute "git clean -fd"
         
     | 
| 
      
 25 
     | 
    
         
            +
                      execute "git stash apply #{label}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                      execute "git stash drop #{label}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "uri"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "net/http"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "json"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 8 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 9 
     | 
    
         
            +
                class VerifyCircleCiStatus < Base      
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    unless env[:github_repo] && ENV["GITHUB_OAUTH_TOKEN"]
         
     | 
| 
      
 12 
     | 
    
         
            +
                      log "WARNING: Skipping verification of Circle CI status because GitHub repo or OAuth token isn't set."
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      return @app.call(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    raise "A GitHub OAuth token is required to check the Circle CI status." unless ENV["GITHUB_OAUTH_TOKEN"]
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    sha = latest_commit(env[:development_branch])
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    uri = URI.parse("https://api.github.com/repos/#{env[:github_repo]}/statuses/#{sha}")
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    connection = Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    connection.use_ssl = true
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    request = Net::HTTP::Get.new(uri.request_uri)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    request["Authorization"] = "token #{ENV["GITHUB_OAUTH_TOKEN"]}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                    response = connection.request(request)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    statuses = JSON.parse(response.body)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    if statuses.find { |s| s["state"] == "success" }
         
     | 
| 
      
 33 
     | 
    
         
            +
                      # Success
         
     | 
| 
      
 34 
     | 
    
         
            +
                    elsif status = statuses.find { |s| %w(failure error).include?(s["state"]) }
         
     | 
| 
      
 35 
     | 
    
         
            +
                      raise "The Circle CI tests for branch '#{env[:development_branch]}' (commit #{sha}) failed. Fix them and try again. See #{status["target_url"]}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                    elsif status = statuses.find { |s| s["state"] == "pending"}
         
     | 
| 
      
 37 
     | 
    
         
            +
                      raise "The Circle CI tests for branch '#{env[:development_branch]}' (commit #{sha}) are still running. Wait for them to finish successfully. See #{status["target_url"]}"
         
     | 
| 
      
 38 
     | 
    
         
            +
                    else
         
     | 
| 
      
 39 
     | 
    
         
            +
                      raise "The Circle CI tests for branch '#{env[:development_branch]}' (commit #{sha}) have not run yet. Wait for them to start and finish successfully."
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "takeoff/stage/base"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Stage
         
     | 
| 
      
 5 
     | 
    
         
            +
                class VerifyGithubUpToDate < Base      
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    log     "Fetching from GitHub"
         
     | 
| 
      
 8 
     | 
    
         
            +
                    execute "git fetch #{env[:github_remote]}"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    unless branches_up_to_date?("#{env[:github_remote]}/#{env[:development_branch]}", env[:development_branch])
         
     | 
| 
      
 11 
     | 
    
         
            +
                      raise "GitHub is not up to date on branch '#{env[:development_branch]}'. Pull and push to synchronize your changes first."
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/takeoff.rb
    ADDED
    
    | 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "active_support/core_ext"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "takeoff/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "takeoff/configuration"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require "takeoff/plan/base"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "takeoff/plan/default"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module Takeoff
         
     | 
| 
      
 10 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 11 
     | 
    
         
            +
                def configuration
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @configuration ||= Configuration.new
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def configure(source = nil, source_location = nil, &block)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  if source
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if source_location
         
     | 
| 
      
 18 
     | 
    
         
            +
                      configuration.instance_eval(source, source_location) 
         
     | 
| 
      
 19 
     | 
    
         
            +
                    else
         
     | 
| 
      
 20 
     | 
    
         
            +
                      configuration.instance_eval(source) 
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  if block
         
     | 
| 
      
 25 
     | 
    
         
            +
                    if block.arity == 1
         
     | 
| 
      
 26 
     | 
    
         
            +
                      block.call(configuration)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    else
         
     | 
| 
      
 28 
     | 
    
         
            +
                      configuration.instance_eval(&block)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                delegate :plans, :[], :plan?, :default_plan, to: :configuration
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def logger
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @logger ||= Logger.new
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              configure do
         
     | 
| 
      
 41 
     | 
    
         
            +
                plan :base,     Plan::Base
         
     | 
| 
      
 42 
     | 
    
         
            +
                plan :default,  Plan::Default
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
    
        data/takeoff.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path("../lib", __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "takeoff/version"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 5 
     | 
    
         
            +
              spec.name           = "takeoff"
         
     | 
| 
      
 6 
     | 
    
         
            +
              spec.version        = Takeoff::VERSION
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.author         = "Douwe Maan"
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.email          = "douwe@selenight.nl"
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.summary        = "Sit back, relax and let Takeoff deploy your app."
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.description    = "Takeoff is a command line tool that helps you deploy your web applications. Configure it once, and from then on Takeoff will take care of responsibly deploying your app, giving you time to get more coffee."
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.homepage       = "https://github.com/DouweM/takeoff"
         
     | 
| 
      
 12 
     | 
    
         
            +
              spec.license        = "MIT"
         
     | 
| 
      
 13 
     | 
    
         
            +
              
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec.files          = `git ls-files -z`.split("\x0")
         
     | 
| 
      
 15 
     | 
    
         
            +
              spec.executables    = ["takeoff"]
         
     | 
| 
      
 16 
     | 
    
         
            +
              spec.require_paths  = ["lib"]
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              spec.add_dependency "activesupport"
         
     | 
| 
      
 19 
     | 
    
         
            +
              spec.add_dependency "middleware"
         
     | 
| 
      
 20 
     | 
    
         
            +
              spec.add_dependency "thor"
         
     | 
| 
      
 21 
     | 
    
         
            +
              spec.add_development_dependency "bundler", "~> 1.7"
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.add_development_dependency "rake", "~> 10.0"
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     |