class Lita::Handlers::CapistranoRails
Public Instance Methods
define_routes(payload)
click to toggle source
# File lib/lita/handlers/capistrano_rails.rb, line 26 def define_routes(payload) define_static_routes define_dinamic_routes end
deploy_env_for_app(response)
click to toggle source
command: “deploy #{env} for #{app}”
# File lib/lita/handlers/capistrano_rails.rb, line 42 def deploy_env_for_app(response) env = response.matches[0][0] app = response.matches[0][1] deploy_app(app, env, response) end
deploy_list_apps(response)
click to toggle source
command: “deploy list”
# File lib/lita/handlers/capistrano_rails.rb, line 32 def deploy_list_apps(response) response.reply_privately('Available apps:') apps = config.apps.map do |app, app_config| envs = app_config[:envs] ? app_config[:envs].keys.join(",") : 'production' "#{app}(#{envs})" end response.reply_privately(apps ) end
deploy_production_for_app(response)
click to toggle source
command: “deploy #{app}”
# File lib/lita/handlers/capistrano_rails.rb, line 49 def deploy_production_for_app(response) env = 'production' app = response.matches[0][0] deploy_app(app, env, response) end
Private Instance Methods
define_dinamic_routes()
click to toggle source
define route for each rapporteur
# File lib/lita/handlers/capistrano_rails.rb, line 206 def define_dinamic_routes config.apps.each do |app, app_config| # define command "deploy APP" self.class.route( %r{deploy (#{app})$}, :deploy_production_for_app, command: true, # restrict_to: [:admins, value[:deploy_group]], help: { "deploy #{app}" => "deploy produciton for #{app}"} ) # define command "deploy ENV for APP" # puts "define route: ^deploy\s+(#{app})\s+(#{area})\s+(.+)\s+(.+)" envs = app_config[:envs] ? app_config[:envs].keys : ['production'] self.class.route( %r{deploy +(\w+) +for +(#{app})$}, :deploy_env_for_app, command: true, # restrict_to: [:admins, value[:deploy_group]], help: { "deploy #{envs.join("|")} for #{app}" => "deploy ENV for #{app}"} ) end end
define_static_routes()
click to toggle source
# File lib/lita/handlers/capistrano_rails.rb, line 196 def define_static_routes self.class.route( %r{deploy\s+list}, :deploy_list_apps, command: true, help: { "deploy list" => "List available apps for deploy"} ) end
deploy_app(app, env, response)
click to toggle source
# File lib/lita/handlers/capistrano_rails.rb, line 57 def deploy_app(app, env, response) app_config = config.apps[app] # check env branch = \ step :validate_deploy_request, :first_step do app_envs = app_config[:envs] ? app_config[:envs].keys : ['production'] # use "production" as default env if !app_envs.include?(env) return response.reply(%{"#{env}" is not available env for #{app}, available env is: #{app_envs.join("|")}}) end branch = app_config[:envs] ? app_config[:envs][env] : 'master' # use "master" as default branch response.reply("I'm deploying #{env} using #{branch} branch for #{app} ...") branch end app_path, app_source_path, bundle_path = \ step :prepare_tmp_dirs do # prepare the dirs app_path = File.expand_path("tmp/capistrano_rails/apps/#{app}") app_source_path = File.expand_path("#{app_path}/source") bundle_path = File.expand_path("tmp/capistrano_rails/bundle") # sharing bundle to reduce space usage and reuse gems FileUtils.mkdir_p(app_path) [app_path, app_source_path, bundle_path] end step :get_source_code do # if dir ".git" exists, use `git pull` if File.exists?("#{app_source_path}/.git") step_log 'Found ".git" exists, run `git pull`' # run_in_dir("git checkout #{branch} && git pull", app_source_path) revision = "origin/#{branch}" # since we're in a local branch already, just reset to specified revision rather than merge run_in_dir("git fetch #{verbose} && git reset #{verbose} --hard #{revision}", app_source_path) else step_log 'not found ".git", run `git clone`' run_in_dir("git clone -b #{branch} #{app_config[:git]} source", app_path) end # TODO: if ".git" exists but repo url changed, clean up the dir then run `git clone` end step :hack_gemfile do # disable "ruby 'x.y.z'" config in Gemfile # to avoid errors like "Your Ruby version is 2.2.4, but your Gemfile specified 2.1.2 (Bundler::RubyVersionMismatch)" gemfile_path = "#{app_source_path}/Gemfile" gemfile_content = File.read gemfile_path if gemfile_content.match(/^ruby .+/) gemfile_content.sub!(/(^ruby .+)/, '# \1 # hacked by Lita::Handlers::CapistranoRails to avoid "Bundler::RubyVersionMismatch" problem') File.open(gemfile_path, 'w') { |gemfile| gemfile.write(gemfile_content) } end end step :run_bundle_install do # run_in_dir("bundle install --quiet", app_source_path) run_in_dir("bundle install --gemfile #{app_source_path}/Gemfile --path #{bundle_path} --deployment --without darwin test", app_source_path) # TODO: check result, reply failure message # TODO: check result, auto retry 1 time if timeout as "Gem::RemoteFetcher::FetchError: Errno::ETIMEDOUT: Operation timed out" end step :run_cap_deploy do # TODO: check "Capfile" # if "Capfile" not exits, reply "not a capistrano project" result = run_in_dir("bundle exec cap #{env} deploy", app_source_path) if result[:exit_status] != 0 # could be 256 failure = %{errrors while executing: "#{result[:cmd]}"\n} failure << result[:stderr] step_fails(response, failure) end end step :reply_deploy_success, :last_step do deploy_success = "deploy #{env} for #{app} finished!" # TODO: get "app_url" app_url = "" deploy_success += ", please visit #{app_url}" if !app_url.empty? response.reply(deploy_success) end end
execute_command(cmd)
click to toggle source
execute commandline and catch stdout and stderr
# File lib/lita/handlers/capistrano_rails.rb, line 153 def execute_command(cmd) log.debug "execute: #{cmd}" full_stdout = String.new full_stderr = String.new started_at = Time.now Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr| stdout_thread = Thread.new do while (line = stdout.gets) do full_stdout += line # printf line end end stderr_thread = Thread.new do while (line = stderr.gets) do full_stderr += line end end stdout_thread.join stderr_thread.join exit_status = wait_thr.value.to_i finished_at = Time.now runtime = finished_at - started_at { cmd: cmd, started_at: started_at, finished_at: finished_at, exit_status: exit_status, runtime: runtime, stdout: full_stdout, stderr: full_stderr, } end end
run_in_dir(cmd, dir)
click to toggle source
# File lib/lita/handlers/capistrano_rails.rb, line 140 def run_in_dir(cmd, dir) lita_mark = "LITA=#{Lita::VERSION}" _cmd = "cd #{dir} && #{lita_mark} #{cmd}" # log.info _cmd # running bundle install inside a bundle-managed shell to avoid "RuntimeError: Specs already loaded" # see https://github.com/bundler/bundler/issues/1981#issuecomment-6292686 Bundler.with_clean_env do # system(_cmd) # can't catch output execute_command(_cmd) end end
verbose()
click to toggle source
# File lib/lita/handlers/capistrano_rails.rb, line 192 def verbose # config.scm_verbose ? nil : "-q" end