capistrano_rails_recipes 0.1.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0e95a6a449ca1d0accd0e50d5ff5871ab73faae
4
+ data.tar.gz: e2298dd4dd97c933e5840791b80fdc20f1537b57
5
+ SHA512:
6
+ metadata.gz: 6412c89829b5bfefcf741b4fdee9181faabf52a0d8d7ca0a5d49c2d025d42d47b172a9e6def08db425f1968bd10903e7e167810c12420c338446e429316df33c
7
+ data.tar.gz: 7a58fe154a6dcc7295e72980b755568ec3a9a8ab261a50da5ff9b44cd7050cf2fbf0cb3bc7cd0c9918caf17da15e6dfeb70f84dc5d9f394ed8c4942b91105454
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Evrone collection of Capistrano recipes
2
+
3
+ We deploy a lot of Rails applications and our developers have to solve similar problems each time during the deployment: how to run workers, how to generate crontab, how to precompile assets faster and so on. This collection of recipes helps us to solve them.
4
+
5
+ Recipe use:
6
+
7
+ * [`foreman`][foreman] + [`foreman_export_runitu`][runitu] to generate runit scripts with the Procfile
8
+ * [`whenever`][whenever] to generate crontab
9
+ * [`unicorn`][unicorn] to run the application
10
+
11
+ It also consider that you use *system wide rbenv* on the server.
12
+
13
+ ##Installation
14
+
15
+ gem 'capistrano_evrone_recipes', :require => false
16
+
17
+ Capfile example:
18
+
19
+ require "capistrano_evrone_recipes/capistrano"
20
+
21
+ set :repository, "git@github.com:..."
22
+ set :application, "my_cook_application"
23
+
24
+ task :production do
25
+ role :web, "web.example.com"
26
+ role :app, "app.example.com"
27
+ role :crontab, "app.example.com"
28
+ role, :db, "db.example.com", :primary => true
29
+ role, :worker, "workers.example.com"
30
+ end
31
+
32
+ task :staging do
33
+ server "stage.example.com", :web, :app, :crontab, :db, :worker
34
+ end
35
+
36
+ As you can see, we use use roles to bind the tasks, and there are some additions to roles and additional roles:
37
+
38
+ **web** compiles assets if content of `app/assets` was changed since last deploy (add FORCE=1 to force the assets compilation)
39
+
40
+ **app** all files from `shared/config` is being symlinked to `current/config` like:
41
+
42
+ shared/config/database.yml -> current/config/database.yml
43
+ shared/config/settings/production.yml -> current/config/settings/production.yml
44
+
45
+ **crontab** generates crontab with `whenever` gem, only if the content of `config/schedule.rb` was changed (add FORCE=1 to force the crontab generation)
46
+
47
+ **db** run migrations only if `db/migrate` was changed (add FORCE=1 to force migrations or SKIP_MIGRATION=1 to skip them)
48
+
49
+ **worker** Procfile exports runit configs to `deploy_to/application/services`
50
+
51
+ On **deploy:restart** unicorn and runit workers is being restarted.
52
+
53
+ You can use some extra `cap` tasks:
54
+
55
+ * `rails:console` to launch `rails console` on remote server
56
+ * `rails:dbconsole` to launch `rails dbconsole` on remote server
57
+ * `login` to open SSH session under user `deploy` and switch catalog to Capistrano's `current_path`
58
+
59
+ **Important**
60
+
61
+ To run succesfully together with system wide rbenv, all you tasks in Procfile must be started with `rbenv exec`
62
+
63
+ ##Capistrano
64
+
65
+ Default variables:
66
+
67
+ logger.level = Capistrano::Logger::DEBUG
68
+ default_run_options[:pty] = true
69
+ ssh_options[:forward_agent] = true
70
+ set :bundle_cmd, "rbenv exec bundle"
71
+ set :bundle_flags, "--deployment --quiet --binstubs --shebang ruby-local-exec"
72
+ set :rake, -> { "#{bundle_cmd} exec rake" }
73
+ set :keep_releases, 7
74
+ set :scm, "git"
75
+ set :user, "deploy"
76
+ set :deploy_via, :unshared_remote_cache
77
+ set :copy_exclude, [".git"]
78
+ set :repository_cache, -> { "#{deploy_to}/shared/#{application}.git" }
79
+ set :normalize_asset_timestamps, false
80
+
81
+ ##Bonus track
82
+
83
+ To enable silent mode, add `ENV['CAP_SILENT_MODE']` before the `require 'capistrano_evrone_recipes/capistrano'` in your `Capfile`
84
+
85
+ ![silent mode](https://www.evernote.com/shard/s38/sh/4ea45631-93bc-4c03-bad8-f0aa40ca637b/8680b09c40342c6a885212b212b1c746/res/b04ff7c4-b29c-41b2-ab0a-6664cf0b75b9/skitch.png)
86
+
87
+
88
+
89
+ [foreman]: https://github.com/ddollar/foreman
90
+ [runitu]: https://github.com/evrone/foreman_export_runitu
91
+ [whenever]: https://github.com/javan/whenever
92
+ [unicorn]: http://unicorn.bogomips.org/
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,24 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "capistrano_rails_recipes/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "capistrano_rails_recipes"
6
+ s.version = CapistranoRailsRecipes::VERSION
7
+
8
+ s.authors = ["Dmitry Galinsky", "Alex Dubovskoy"]
9
+ s.email = "dubovskoy.a@gmail.com"
10
+ s.homepage = "https://github.com/dubadub/capistrano_rails_recipes"
11
+ s.summary = "Capistrano recipes for rails app"
12
+
13
+ s.description = s.summary
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency("capistrano", ["= 2.15.5"])
21
+ s.add_runtime_dependency("foreman", [">= 0"])
22
+ s.add_runtime_dependency("foreman_export_runitu", [">= 0"])
23
+ s.add_runtime_dependency("whenever", ["~> 0.8.4"])
24
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/util"
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ logger.level = Capistrano::Logger::DEBUG
5
+
6
+ default_run_options[:pty] = true
7
+ ssh_options[:forward_agent] = true
8
+
9
+ set :bundle_cmd, "rbenv exec bundle"
10
+ set :bundle_flags, "--deployment --quiet"
11
+ set :rake, -> { "#{bundle_cmd} exec rake" }
12
+ set :keep_releases, 7
13
+ set :scm, "git"
14
+ set :user, "deploy"
15
+ set :deploy_via, :unshared_remote_cache
16
+ set :copy_exclude, [".git"]
17
+ set :repository_cache, -> { "#{deploy_to}/shared/#{application}.git" }
18
+ set :normalize_asset_timestamps, false
19
+ set :use_sudo, false
20
+
21
+ load "deploy"
22
+ require 'bundler/capistrano'
23
+
24
+ recipes_dir = File.dirname(File.expand_path(__FILE__))
25
+
26
+ #disabled_modules = fetch(:disabled_features, [])
27
+
28
+ load "#{recipes_dir}/recipes/crontab.rb"
29
+ load "#{recipes_dir}/recipes/runit.rb"
30
+ load "#{recipes_dir}/recipes/deploy.rb"
31
+ load "#{recipes_dir}/recipes/login.rb"
32
+ load "#{recipes_dir}/recipes/migrate.rb"
33
+ load "#{recipes_dir}/recipes/rails.rb"
34
+ #load "#{recipes_dir}/recipes/unicorn.rb"
35
+ load "#{recipes_dir}/recipes/assets.rb"
36
+ end
@@ -0,0 +1,60 @@
1
+ _cset :asset_env, "RAILS_GROUPS=assets"
2
+ _cset :assets_prefix, "assets"
3
+ _cset :assets_role, [:web]
4
+
5
+ _cset :normalize_asset_timestamps, false
6
+
7
+ before 'deploy:finalize_update', 'deploy:assets:symlink'
8
+ after 'deploy:update_code', 'deploy:assets:precompile'
9
+
10
+ namespace :deploy do
11
+ namespace :assets do
12
+ desc <<-DESC
13
+ [internal] This task will set up a symlink to the shared directory \
14
+ for the assets directory. Assets are shared across deploys to avoid \
15
+ mid-deploy mismatches between old application html asking for assets \
16
+ and getting a 404 file not found error. The assets cache is shared \
17
+ for efficiency. If you customize the assets path prefix, override the \
18
+ :assets_prefix variable to match.
19
+ DESC
20
+ task :symlink, :on_no_matching_servers => :continue, :roles => assets_role, :except => { :no_release => true } do
21
+ run <<-CMD
22
+ rm -rf #{latest_release}/public/#{assets_prefix} &&
23
+ mkdir -p #{latest_release}/public &&
24
+ mkdir -p #{shared_path}/assets &&
25
+ ln -s #{shared_path}/assets #{latest_release}/public/#{assets_prefix}
26
+ CMD
27
+ end
28
+
29
+ desc <<-DESC
30
+ Run the asset precompilation rake task. You can specify the full path \
31
+ to the rake executable by setting the rake variable. You can also \
32
+ specify additional environment variables to pass to rake via the \
33
+ asset_env variable. The defaults are:
34
+
35
+ set :rake, "rake"
36
+ set :rails_env, "production"
37
+ set :asset_env, "RAILS_GROUPS=assets"
38
+ DESC
39
+ task :precompile, :on_no_matching_servers => :continue, :roles => assets_role, :except => { :no_release => true } do
40
+ CapistranoRecipes::Util.ensure_changed_remote_dirs(self, "app/assets") do
41
+ run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile"
42
+ end
43
+ end
44
+
45
+ desc <<-DESC
46
+ Run the asset clean rake task. Use with caution, this will delete \
47
+ all of your compiled assets. You can specify the full path \
48
+ to the rake executable by setting the rake variable. You can also \
49
+ specify additional environment variables to pass to rake via the \
50
+ asset_env variable. The defaults are:
51
+
52
+ set :rake, "rake"
53
+ set :rails_env, "production"
54
+ set :asset_env, "RAILS_GROUPS=assets"
55
+ DESC
56
+ task :clean, :on_no_matching_servers => :continue, :roles => assets_role, :except => { :no_release => true } do
57
+ run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:clean"
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ set(:whenever_command) { "#{fetch(:bundle_cmd)} exec whenever" }
2
+ set(:whenever_variables) {"\"environment=#{rails_env}&path=#{current_path}&output=#{shared_path}/log/crontab.log\"" }
3
+ set(:whenever_roles) { :crontab }
4
+
5
+ require "whenever/capistrano/recipes"
6
+
7
+ namespace :crontab do
8
+ desc "Generate crontab from config/whenever.rb"
9
+ task :generate, :roles => :crontab, :on_no_matching_servers => :continue, :except => { :no_release => true } do
10
+ if find_servers_for_task(current_task).any?
11
+ CapistranoRecipes::Util.ensure_changed_remote_files(self, "config/schedule.rb") do
12
+ find_and_execute_task("whenever:update_crontab")
13
+ end
14
+ end
15
+ end
16
+
17
+ desc "Clear crontab"
18
+ task :clear, :roles => :crontab, :on_no_matching_servers => :continue, :except => { :no_release => true } do
19
+ if find_servers_for_task(current_task).any?
20
+ find_and_execute_task("whenever:clear_crontab")
21
+ end
22
+ end
23
+ end
24
+
25
+ after "deploy:restart", 'crontab:generate'
@@ -0,0 +1,34 @@
1
+ namespace :deploy do
2
+
3
+ task :symlink_configs do
4
+ s = "cd #{shared_path}/config && "
5
+ s << "for i in `find . -type f | sed 's/^\\.\\///'` ; do "
6
+ s << "echo \"create current/config/${i}\" ;"
7
+ s << "rm -f #{release_path}/config/${i} ;"
8
+ s << "ln -snf #{shared_path}/config/${i} #{release_path}/config/${i} ; done"
9
+ run s
10
+ end
11
+
12
+ task :setup_config, roles: :app do
13
+ sudo "ln -nfs #{current_path}/config/nginx.conf /opt/nginx/conf/sites-enabled/#{application}"
14
+
15
+ run "mkdir -p #{shared_path}/config"
16
+ run "mkdir -p #{deploy_to}/services"
17
+
18
+ put File.read("config/database.example.yml"), "#{shared_path}/config/database.yml"
19
+ puts "Now edit the config files in #{shared_path}."
20
+ end
21
+
22
+
23
+ task :start, :on_no_matching_servers => :continue, :except => { :no_release => true } do
24
+ end
25
+
26
+ task :stop, :on_no_matching_servers => :continue, :except => { :no_release => true } do
27
+ end
28
+
29
+ task :restart, :on_no_matching_servers => :continue, :except => {:no_release => true} do
30
+ end
31
+ end
32
+
33
+ after 'deploy:finalize_update', 'deploy:symlink_configs'
34
+ after 'deploy:setup', 'deploy:setup_config'
@@ -0,0 +1,6 @@
1
+ desc "Login to remote host"
2
+ task :login do
3
+ hostname = find_servers_for_task(current_task).first
4
+ port = hostname.port || fetch(:port, 22)
5
+ exec "ssh -A -p #{port} -l #{user} #{hostname} -t 'cd #{current_path} && ${SHELL} -l'"
6
+ end
@@ -0,0 +1,14 @@
1
+ namespace :deploy do
2
+ desc "Migrate database if has migration"
3
+ task :migrate, :roles => :db, :on_no_matching_servers => :continue, :only => {:primary => true}, :except => { :no_release => true } do
4
+ return if ENV['MIGRATE_SKIP']
5
+
6
+ if find_servers_for_task(current_task).any?
7
+ CapistranoRecipes::Util.ensure_changed_remote_dirs(self, "db/migrate") do
8
+ run "cd #{release_path} && #{fetch :rake} RAILS_ENV=#{rails_env} db:migrate"
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ after "deploy:finalize_update", "deploy:migrate"
@@ -0,0 +1,22 @@
1
+ namespace :rails do
2
+ desc "Run rails console"
3
+ desc "open remote console (only on the last machine from the :app roles)"
4
+ task :console, :roles => :app do
5
+ server = find_servers_for_task(current_task).first
6
+ if server
7
+ port = server.port || fetch(:port, 22)
8
+ cmd = "ssh -p #{port} -l #{user} -A #{server} -t 'cd #{current_path} && #{fetch :bundle_cmd} exec rails console #{rails_env}'"
9
+ exec cmd
10
+ end
11
+ end
12
+
13
+ desc "Run rails dbconsole"
14
+ desc "open remote dbconsole (only on the primary db machine)"
15
+ task :dbconsole, :roles => :db, :only => { :primary => true } do
16
+ server = find_servers_for_task(current_task).first
17
+ if server
18
+ port = server.port || fetch(:port, 22)
19
+ exec "ssh -p #{port} -l #{user} -A #{server} -t 'cd #{current_path} && #{fetch :bundle_cmd} exec rails dbconsole #{rails_env}'"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,80 @@
1
+ _cset(:runit_export_path) { "#{latest_release}/var/services" }
2
+ _cset(:runit_services_path) { "#{deploy_to}/services" }
3
+ _cset(:runit_export_cmd) { "#{fetch :bundle_cmd} exec foreman export runitu" }
4
+ _cset(:runit_procfile) { "Procfile" }
5
+ _cset(:foreman_concurency) { nil }
6
+ _cset(:runit_restart_timeout) { 10 }
7
+ _cset(:runit_restart_cmd) { "sv -w #{fetch :runit_restart_timeout, 10} -v t $(pwd)/* || echo 'failed'" }
8
+
9
+ namespace :runit do
10
+
11
+ desc "Restart Procfile services"
12
+ task :restart, :roles => :worker, :on_no_matching_servers => :continue, :except => { :no_release => true } do
13
+ if find_servers_for_task(current_task).any?
14
+ cmd = %Q{
15
+ if [ -d #{runit_export_path} ] ; then
16
+ echo -n "----> Update services" ;
17
+ rm -rf #{runit_services_path}/* ;
18
+ sync ;
19
+ cp -r #{runit_export_path}/* #{runit_services_path}/ ;
20
+ sync ;
21
+ rm -rf #{runit_export_path} ;
22
+ else
23
+ echo -n "----> Restart services" ;
24
+ test $(ls -1 #{runit_services_path} | wc -l) -eq 0 ||
25
+ (cd #{fetch :runit_services_path} && #{fetch :runit_restart_cmd, "/bin/true"}) ;
26
+ fi
27
+ }.compact
28
+ run cmd
29
+ end
30
+ end
31
+
32
+ desc "Stop services"
33
+ task :stop, :roles => :worker, :on_no_matching_servers => :continue, :except => { :no_release => true } do
34
+ if find_servers_for_task(current_task).any?
35
+ run "sv -w 10 force-stop #{runit_services_path}/*"
36
+ end
37
+ end
38
+
39
+ desc "Start services"
40
+ task :start, :roles => :worker, :on_no_matching_servers => :continue, :except => { :no_release => true } do
41
+ if find_servers_for_task(current_task).any?
42
+ run "sv -v start #{runit_services_path}/*"
43
+ end
44
+ end
45
+
46
+ desc "Export Procfile"
47
+ task :export, :roles => :worker, :on_no_matching_servers => :continue, :except => { :no_release => true } do
48
+ if find_servers_for_task(current_task).any?
49
+ env = %{ RAILS_ENV=#{rails_env} }.strip + "\n"
50
+ put(env, "#{latest_release}/.env")
51
+
52
+ c = fetch(:foreman_concurency) ? "-c #{fetch :foreman_concurency}" : ""
53
+ diff = ENV['FORCE'] ?
54
+ %{ /bin/false } :
55
+ %{ diff -q #{previous_release}/#{runit_procfile} #{latest_release}/#{runit_procfile} > /dev/null }
56
+ cmd = %{
57
+ #{diff} || (
58
+ echo -n "----> Export #{runit_procfile}" ;
59
+ cd #{latest_release} &&
60
+ #{runit_export_cmd} #{runit_export_path}
61
+ -e #{latest_release}/.env
62
+ -l #{shared_path}/log
63
+ -f #{latest_release}/#{runit_procfile}
64
+ --root=#{current_path}
65
+ -a #{application} #{c} > /dev/null &&
66
+
67
+ for i in $(ls #{runit_export_path}/); do
68
+ sed -i 's|#{runit_export_path}|#{runit_services_path}|g' #{runit_export_path}/${i}/run ;
69
+ done
70
+ )
71
+ }.compact
72
+ run cmd
73
+ end
74
+ end
75
+ end
76
+
77
+ after "deploy:finalize_update", "runit:export"
78
+ after "deploy:start", "runit:start"
79
+ after "deploy:stop", "runit:stop"
80
+ after "deploy:restart", "runit:restart"
@@ -0,0 +1,64 @@
1
+ require 'colored'
2
+
3
+ logger.level = Capistrano::Logger::IMPORTANT
4
+
5
+ STDOUT.sync
6
+
7
+ $silent_stack = []
8
+ $silent_stack_tm = []
9
+ $silent_stack_cur = nil
10
+ $silent_stack_skip = nil
11
+
12
+ def format_silent(name, options = {})
13
+ s = name.size
14
+ i = (70 - s).abs
15
+ #name = name.bold
16
+ if options[:bold]
17
+ name = name.gsub(/ [_a-z:]+/) do |a|
18
+ a.bold
19
+ end
20
+ end
21
+ print(name + (" " * i))
22
+ end
23
+
24
+ on :before do
25
+ $silent_stack_tm.push Time.now.to_f
26
+
27
+ name = current_task.fully_qualified_name
28
+ if $silent_stack_cur && $silent_stack_cur == $silent_stack.last
29
+ puts ""
30
+ end
31
+ $silent_stack.push name
32
+ $silent_stack_cur = name
33
+
34
+ roles = current_task.instance_eval{ @options[:roles] }
35
+
36
+ name = "#{name} [#{[roles].flatten.map(&:to_s).join(',')}]" if roles
37
+ format_silent((" " * ($silent_stack.size - 1)) + "* #{name}", :bold => true)
38
+ end
39
+
40
+ on :after do
41
+ name = current_task.fully_qualified_name
42
+ old = $silent_stack.pop
43
+ tm = $silent_stack_tm.pop
44
+ tm = Time.now.to_f - tm
45
+
46
+ spaces = $silent_stack.size
47
+ rs = "DONE".green
48
+ rs += (" %0.2fs" % tm).to_s
49
+
50
+ if $silent_stack_skip == true
51
+ rs = "SKIP".yellow
52
+ $silent_stack_skip = nil
53
+ end
54
+
55
+ if old == $silent_stack_cur
56
+ puts rs
57
+ else
58
+ format_silent((" " * (spaces)) + "...", :bold => true)
59
+ puts rs
60
+ end
61
+
62
+ $silent_stack_cur = nil
63
+ end
64
+
@@ -0,0 +1,6 @@
1
+ namespace :sphinx do
2
+ desc "Sphinx rebuild"
3
+ task :rebuild, :roles => :sphinx, :on_no_matching_servers => :continue, :except => { :no_release => true } do
4
+ run("cd #{current_path} && bundle exec rake ts:rebuild RAILS_ENV=#{rails_env}")
5
+ end
6
+ end
@@ -0,0 +1,28 @@
1
+ _cset(:unicorn_binary) { "#{fetch :bundle_cmd} exec unicorn" }
2
+ _cset(:unicorn_config) { "#{fetch :current_path}/config/unicorn.rb" }
3
+ _cset(:unicorn_pid) { "#{fetch :current_path}/tmp/pids/unicorn.pid" }
4
+
5
+ namespace :unicorn do
6
+ desc "Restart unicorn"
7
+ task :restart, :roles => :app, :on_no_matching_servers => :continue, :except => {:no_release => true} do
8
+ upid = fetch :unicorn_pid
9
+ cmd = <<-EOF
10
+ if [ -f #{upid} ] ; then kill -s USR2 `cat #{upid}` ;fi && a=1;d=2; echo 'Please wait unicorn restart...'; sleep 1 && while [ -e #{upid}.oldbin ] ; do sleep 2; a=$(expr $a + $d); done; echo "Unicorn restart time: $a sec"
11
+ EOF
12
+ run cmd
13
+ end
14
+
15
+ desc "Start unicorn"
16
+ task :start, :roles => :app, :on_no_matching_servers => :continue, :except => {:no_release => true} do
17
+ run "cd #{current_path} && env #{fetch :unicorn_binary} -c #{fetch :unicorn_config} -E #{rails_env} -D"
18
+ end
19
+
20
+ desc "Stop unicorn"
21
+ task :stop, :roles => :app, :on_no_matching_servers => :continue, :except => {:no_release => true} do
22
+ run "test -f #{fetch :unicorn_pid} && kill `cat #{fetch :unicorn_pid}`"
23
+ end
24
+ end
25
+
26
+ after "deploy:start", "unicorn:start"
27
+ after "deploy:stop", "unicorn:stop"
28
+ after "deploy:restart", "unicorn:restart"
@@ -0,0 +1,28 @@
1
+ module CapistranoRailsRecipes
2
+ class Util
3
+ class << self
4
+ def ensure_changed_remote_dirs(cap, path)
5
+ yield
6
+ end
7
+
8
+ def ensure_changed_remote_files(cap, path)
9
+ yield
10
+ end
11
+
12
+ def changed?(cap, path, options = {})
13
+ r = options[:recursive] ? "-r" : ""
14
+ %{
15
+ test -e #{cap.previous_release}/#{path} &&
16
+ diff #{r} #{cap.previous_release}/#{path} #{cap.latest_release}/#{path} > /dev/null
17
+ ;
18
+ ST=$? ;
19
+ if [ $ST -eq 0 ] ; then
20
+ echo -n '----> #{path} is not changed' ;
21
+ else
22
+ echo -n '----> #{path} is changed' ;
23
+ fi
24
+ }.compact
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module CapistranoRailsRecipes
2
+ class VERSION
3
+
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ PATCH = 21
7
+
8
+ def self.to_s
9
+ "#{MAJOR}.#{MINOR}.#{PATCH}"
10
+ end
11
+
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano_rails_recipes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.21
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Galinsky
8
+ - Alex Dubovskoy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: capistrano
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '='
19
+ - !ruby/object:Gem::Version
20
+ version: 2.15.5
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '='
26
+ - !ruby/object:Gem::Version
27
+ version: 2.15.5
28
+ - !ruby/object:Gem::Dependency
29
+ name: foreman
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: foreman_export_runitu
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: whenever
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 0.8.4
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.8.4
70
+ description: Capistrano recipes for rails app
71
+ email: dubovskoy.a@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - README.md
79
+ - Rakefile
80
+ - capistrano_rails_recipes.gemspec
81
+ - lib/capistrano_rails_recipes/capistrano.rb
82
+ - lib/capistrano_rails_recipes/recipes/assets.rb
83
+ - lib/capistrano_rails_recipes/recipes/crontab.rb
84
+ - lib/capistrano_rails_recipes/recipes/deploy.rb
85
+ - lib/capistrano_rails_recipes/recipes/login.rb
86
+ - lib/capistrano_rails_recipes/recipes/migrate.rb
87
+ - lib/capistrano_rails_recipes/recipes/rails.rb
88
+ - lib/capistrano_rails_recipes/recipes/runit.rb
89
+ - lib/capistrano_rails_recipes/recipes/silent.rb
90
+ - lib/capistrano_rails_recipes/recipes/sphinx.rb
91
+ - lib/capistrano_rails_recipes/recipes/unicorn.rb
92
+ - lib/capistrano_rails_recipes/util.rb
93
+ - lib/capistrano_rails_recipes/version.rb
94
+ homepage: https://github.com/dubadub/capistrano_rails_recipes
95
+ licenses: []
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.0.14
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Capistrano recipes for rails app
117
+ test_files: []