capistrano-deploy 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Gemfile.lock +10 -10
- data/MIT-LICENSE +19 -0
- data/README.md +70 -28
- data/capistrano-deploy.gemspec +1 -1
- data/lib/capistrano-deploy.rb +12 -4
- data/lib/capistrano-deploy/bundler.rb +2 -0
- data/lib/capistrano-deploy/git.rb +4 -0
- data/lib/capistrano-deploy/multistage.rb +53 -8
- data/lib/capistrano-deploy/rails_assets.rb +25 -0
- data/lib/capistrano-deploy/rvm.rb +12 -2
- data/lib/capistrano-deploy/whenever.rb +1 -1
- data/spec/bundle_spec.rb +14 -0
- data/spec/deploy_spec.rb +17 -3
- data/spec/git_spec.rb +4 -1
- data/spec/multistage_spec.rb +43 -10
- data/spec/passenger_spec.rb +2 -4
- data/spec/rails_assets_spec.rb +39 -0
- data/spec/rails_spec.rb +5 -8
- data/spec/spec_helper.rb +49 -12
- data/spec/unicorn_spec.rb +3 -3
- data/spec/whenever_spec.rb +24 -1
- metadata +15 -8
- data/lib/capistrano-deploy/deploy.rb +0 -65
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
capistrano-deploy (0.
|
4
|
+
capistrano-deploy (0.3.0)
|
5
5
|
capistrano (~> 2.9.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -14,23 +14,23 @@ GEM
|
|
14
14
|
net-ssh (>= 2.0.14)
|
15
15
|
net-ssh-gateway (>= 1.1.0)
|
16
16
|
diff-lcs (1.1.3)
|
17
|
-
highline (1.6.
|
17
|
+
highline (1.6.9)
|
18
18
|
net-scp (1.0.4)
|
19
19
|
net-ssh (>= 1.99.1)
|
20
20
|
net-sftp (2.0.5)
|
21
21
|
net-ssh (>= 2.0.9)
|
22
|
-
net-ssh (2.2.
|
22
|
+
net-ssh (2.2.2)
|
23
23
|
net-ssh-gateway (1.1.0)
|
24
24
|
net-ssh (>= 1.99.1)
|
25
25
|
rake (0.9.2.2)
|
26
|
-
rspec (2.
|
27
|
-
rspec-core (~> 2.
|
28
|
-
rspec-expectations (~> 2.
|
29
|
-
rspec-mocks (~> 2.
|
30
|
-
rspec-core (2.
|
31
|
-
rspec-expectations (2.
|
26
|
+
rspec (2.8.0)
|
27
|
+
rspec-core (~> 2.8.0)
|
28
|
+
rspec-expectations (~> 2.8.0)
|
29
|
+
rspec-mocks (~> 2.8.0)
|
30
|
+
rspec-core (2.8.0)
|
31
|
+
rspec-expectations (2.8.0)
|
32
32
|
diff-lcs (~> 1.1.2)
|
33
|
-
rspec-mocks (2.
|
33
|
+
rspec-mocks (2.8.0)
|
34
34
|
|
35
35
|
PLATFORMS
|
36
36
|
ruby
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2012 Sergey Nartimov
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
-
Capistrano deploy recipes
|
1
|
+
Capistrano deploy recipes [![TravisCI](https://secure.travis-ci.org/lest/capistrano-deploy.png?branch=master)](http://travis-ci.org/lest/capistrano-deploy)
|
2
2
|
=========================
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
Inspired by https://github.com/blog/470-deployment-script-spring-cleaning.
|
5
|
+
|
6
|
+
Quickstart with Git and Rails
|
7
|
+
-----------------------------
|
6
8
|
|
7
9
|
Minimal Capfile for Rails deploy using Git:
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
```ruby
|
12
|
+
require 'capistrano-deploy'
|
13
|
+
use_recipes :git, :rails
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
server 'server name or ip address', :web, :app, :db, :primary => true
|
16
|
+
set :user, 'user for deploy'
|
17
|
+
set :deploy_to, '/deploy/to/path'
|
18
|
+
set :repository, 'your git repository'
|
19
|
+
```
|
16
20
|
|
17
21
|
To setup:
|
18
22
|
|
@@ -22,60 +26,98 @@ Then when you push some changes to git repository simply run:
|
|
22
26
|
|
23
27
|
cap deploy
|
24
28
|
|
25
|
-
|
29
|
+
Or if you have migrations:
|
26
30
|
|
27
31
|
cap deploy:migrations
|
28
32
|
|
29
|
-
To look through changes to be deployed:
|
33
|
+
To look through the changes to be deployed:
|
30
34
|
|
31
35
|
cap deploy:pending
|
32
36
|
|
33
37
|
Multistage
|
34
38
|
----------
|
35
39
|
|
36
|
-
|
40
|
+
Basic usage:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
use_recipe :multistage
|
44
|
+
|
45
|
+
set :default_stage, :development
|
46
|
+
|
47
|
+
stage :development do
|
48
|
+
...
|
49
|
+
end
|
50
|
+
|
51
|
+
stage :production do
|
52
|
+
...
|
53
|
+
end
|
54
|
+
```
|
37
55
|
|
38
|
-
|
56
|
+
You can also pass options that allow setting variables and default stage:
|
39
57
|
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
```ruby
|
59
|
+
stage :development, :branch => :develop, :default => true
|
60
|
+
stage :production, :branch => :master
|
61
|
+
```
|
43
62
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
63
|
+
When branches are specified for stages and git recipe is used
|
64
|
+
it will automatically select stage based on current local branch.
|
47
65
|
|
48
66
|
Bundle
|
49
67
|
------
|
50
68
|
|
51
|
-
|
69
|
+
Use recipe:
|
52
70
|
|
53
|
-
|
71
|
+
```ruby
|
72
|
+
use_recipe :bundle
|
73
|
+
```
|
54
74
|
|
55
|
-
|
75
|
+
And add callback to run `bundle install` on each deploy:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
after 'deploy:update', 'bundle:install'
|
79
|
+
```
|
56
80
|
|
57
81
|
Passenger
|
58
82
|
---------
|
59
83
|
|
60
|
-
|
84
|
+
Use recipe:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
use_recipe :passenger
|
88
|
+
```
|
89
|
+
|
90
|
+
It will automatically do `touch tmp/restart.txt` on each deploy.
|
61
91
|
|
62
92
|
Unicorn
|
63
93
|
-------
|
64
94
|
|
65
|
-
|
95
|
+
Use recipe:
|
66
96
|
|
67
|
-
|
97
|
+
```ruby
|
98
|
+
use_recipe :unicorn
|
99
|
+
```
|
68
100
|
|
69
|
-
|
101
|
+
You can setup callback to reload unicorn after deploy is done:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
after 'deploy:restart', 'unicorn:reload'
|
105
|
+
```
|
70
106
|
|
71
107
|
Whenever
|
72
108
|
--------
|
73
109
|
|
74
|
-
|
110
|
+
Use recipe:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
use_recipe :whenever
|
114
|
+
```
|
75
115
|
|
76
116
|
To automatically update crontab file:
|
77
117
|
|
78
|
-
|
118
|
+
```ruby
|
119
|
+
after 'deploy:restart', 'whenever:update_crontab'
|
120
|
+
```
|
79
121
|
|
80
122
|
You can also clear crontab file with command:
|
81
123
|
|
data/capistrano-deploy.gemspec
CHANGED
data/lib/capistrano-deploy.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
1
3
|
module CapistranoDeploy
|
2
4
|
def self.load_into(configuration)
|
3
5
|
configuration.load do
|
4
6
|
@used_recipes = []
|
5
7
|
|
6
|
-
|
8
|
+
class << self
|
7
9
|
attr_reader :used_recipes
|
10
|
+
end
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
def use_recipe(recipe_name)
|
13
|
+
return if @used_recipes.include?(recipe_name.to_sym)
|
11
14
|
|
15
|
+
begin
|
12
16
|
require "capistrano-deploy/#{recipe_name}"
|
17
|
+
|
13
18
|
recipe = CapistranoDeploy.const_get(recipe_name.to_s.capitalize.gsub(/_(\w)/) { $1.upcase })
|
14
|
-
recipe.load_into(
|
19
|
+
recipe.load_into(self)
|
20
|
+
@used_recipes << recipe.to_s.split('::').last.downcase.to_sym
|
21
|
+
rescue LoadError
|
22
|
+
abort "Are you misspelled `#{recipe_name}` recipe name?"
|
15
23
|
end
|
16
24
|
end
|
17
25
|
|
@@ -11,6 +11,10 @@ module CapistranoDeploy
|
|
11
11
|
|
12
12
|
set(:current_revision) { capture("cd #{deploy_to} && git rev-parse HEAD").chomp }
|
13
13
|
|
14
|
+
set :local_branch do
|
15
|
+
`git symbolic-ref HEAD 2> /dev/null`.strip.sub('refs/heads/', '')
|
16
|
+
end
|
17
|
+
|
14
18
|
namespace :deploy do
|
15
19
|
desc 'Setup'
|
16
20
|
task :setup, :except => {:no_release => true} do
|
@@ -2,24 +2,37 @@ module CapistranoDeploy
|
|
2
2
|
module Multistage
|
3
3
|
def self.load_into(configuration)
|
4
4
|
configuration.load do
|
5
|
-
set :
|
5
|
+
set :multistage_config, Config.new(configuration)
|
6
6
|
|
7
|
-
def define_stage(
|
8
|
-
|
7
|
+
def define_stage(*args, &block)
|
8
|
+
warn "[DEPRECATION] `define_stage` is deprecated, use `stage` instead"
|
9
|
+
stage(*args, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def stage(name, options={}, &block)
|
13
|
+
set :default_stage, name.to_sym if options.delete(:default)
|
14
|
+
multistage_config.stage(name, options)
|
9
15
|
callbacks[:start].detect { |c| c.source == 'multistage:ensure' }.except << name.to_s
|
16
|
+
|
10
17
|
task(name) do
|
11
|
-
set :
|
12
|
-
|
18
|
+
set :current_stage, name.to_s
|
19
|
+
options.each do |k, v|
|
20
|
+
set k, v if v
|
21
|
+
end
|
22
|
+
block.call if block
|
13
23
|
end
|
14
24
|
end
|
15
25
|
|
16
26
|
namespace :multistage do
|
17
27
|
task :ensure do
|
18
|
-
unless exists?(:
|
19
|
-
if
|
28
|
+
unless exists?(:current_stage)
|
29
|
+
if stage = multistage_config.inferred_stage
|
30
|
+
find_and_execute_task(stage.name)
|
31
|
+
elsif exists?(:default_stage)
|
20
32
|
find_and_execute_task(default_stage)
|
21
33
|
else
|
22
|
-
|
34
|
+
stage_names = multistage_config.stages.map(&:name)
|
35
|
+
abort "No stage specified. Please specify one of: #{stage_names.join(', ')} (e.g. `cap #{stage_names.first} #{ARGV.last}')"
|
23
36
|
end
|
24
37
|
end
|
25
38
|
end
|
@@ -28,5 +41,37 @@ module CapistranoDeploy
|
|
28
41
|
on :start, 'multistage:ensure'
|
29
42
|
end
|
30
43
|
end
|
44
|
+
|
45
|
+
# Handles multistage configuration
|
46
|
+
class Config
|
47
|
+
attr_reader :config
|
48
|
+
attr_reader :stages
|
49
|
+
|
50
|
+
def initialize(config)
|
51
|
+
@config = config
|
52
|
+
@stages = []
|
53
|
+
end
|
54
|
+
|
55
|
+
def stage(name, options={})
|
56
|
+
stages << Stage.new(name, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def inferred_stage
|
60
|
+
if config.using_recipe?(:git)
|
61
|
+
branch = config.local_branch
|
62
|
+
stages.find { |stage| stage.options[:branch].to_s == branch }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Stage
|
68
|
+
attr_reader :name
|
69
|
+
attr_reader :options
|
70
|
+
|
71
|
+
def initialize(name, options={})
|
72
|
+
@name = name
|
73
|
+
@options = options
|
74
|
+
end
|
75
|
+
end
|
31
76
|
end
|
32
77
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CapistranoDeploy
|
2
|
+
module RailsAssets
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
use_recipe :rails
|
6
|
+
|
7
|
+
namespace :deploy do
|
8
|
+
namespace :assets do
|
9
|
+
desc 'Precompile assets'
|
10
|
+
task :precompile do
|
11
|
+
run "cd #{deploy_to} && RAILS_ENV=#{rails_env} RAILS_GROUPS=assets #{rake} assets:precompile"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Clean assets'
|
15
|
+
task :clean do
|
16
|
+
run "cd #{deploy_to} && RAILS_ENV=#{rails_env} RAILS_GROUPS=assets #{rake} assets:clean"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
after 'deploy:update', 'deploy:assets:precompile'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,8 +2,18 @@ module CapistranoDeploy
|
|
2
2
|
module Rvm
|
3
3
|
def self.load_into(configuration)
|
4
4
|
configuration.load do
|
5
|
-
|
6
|
-
|
5
|
+
set :rvm_ruby_string, 'default'
|
6
|
+
set :rvm_path, '/usr/local/rvm'
|
7
|
+
|
8
|
+
set(:rvm_shell_path) { "#{rvm_path}/bin/rvm-shell" }
|
9
|
+
|
10
|
+
set :default_shell do
|
11
|
+
shell = rvm_shell_path
|
12
|
+
ruby = rvm_ruby_string.to_s.strip
|
13
|
+
shell = "rvm_path=#{rvm_path} #{shell} '#{ruby}'" unless ruby.empty?
|
14
|
+
|
15
|
+
shell
|
16
|
+
end
|
7
17
|
|
8
18
|
if File.exists?('.rvmrc')
|
9
19
|
matches = File.read('.rvmrc').scan(/^rvm\s+use\s+.*?([\w\-\.]+@[\w\-]+).*$/)
|
data/spec/bundle_spec.rb
ADDED
data/spec/deploy_spec.rb
CHANGED
@@ -2,7 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'deploy' do
|
4
4
|
before do
|
5
|
-
mock_config
|
5
|
+
mock_config do
|
6
|
+
use_recipes :git, :rails
|
7
|
+
set :deploy_to, '/foo/bar'
|
8
|
+
end
|
6
9
|
end
|
7
10
|
|
8
11
|
it 'returns used recipes' do
|
@@ -14,11 +17,22 @@ describe 'deploy' do
|
|
14
17
|
config.should_not be_using_recipe(:bundle)
|
15
18
|
end
|
16
19
|
|
20
|
+
it 'uses recipe once' do
|
21
|
+
config.use_recipe :git
|
22
|
+
config.used_recipes.should == [:git, :rails]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'aborts when recipe name misspelled' do
|
26
|
+
with_stderr do |output|
|
27
|
+
expect { config.use_recipe(:rvn) }.to raise_error(SystemExit)
|
28
|
+
output.should include('Are you misspelled `rvn` recipe name?')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
17
32
|
describe 'deploy' do
|
18
33
|
it 'runs update and restart' do
|
19
|
-
config.namespaces[:deploy].should_receive(:update)
|
20
|
-
config.namespaces[:deploy].should_receive(:restart)
|
21
34
|
cli_execute 'deploy'
|
35
|
+
config.should have_executed('deploy:update', 'deploy:restart')
|
22
36
|
end
|
23
37
|
end
|
24
38
|
end
|
data/spec/git_spec.rb
CHANGED
data/spec/multistage_spec.rb
CHANGED
@@ -6,14 +6,9 @@ describe 'multistage' do
|
|
6
6
|
use_recipes :multistage
|
7
7
|
|
8
8
|
set :default_stage, :development
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
define_stage :production do
|
15
|
-
set :foo, 'baz'
|
16
|
-
end
|
9
|
+
stage(:development, :branch => 'develop') { set :foo, 'bar' }
|
10
|
+
stage(:production, :branch => 'master') { set :foo, 'baz' }
|
11
|
+
stage :another_stage, :foo => 'bar'
|
17
12
|
|
18
13
|
task(:example) {}
|
19
14
|
end
|
@@ -21,13 +16,51 @@ describe 'multistage' do
|
|
21
16
|
|
22
17
|
it 'uses default stage' do
|
23
18
|
cli_execute 'example'
|
24
|
-
config.
|
19
|
+
config.current_stage.should == 'development'
|
25
20
|
config.foo.should == 'bar'
|
26
21
|
end
|
27
22
|
|
23
|
+
it 'aborts when no stage selected' do
|
24
|
+
with_stderr do |output|
|
25
|
+
config.unset :default_stage
|
26
|
+
expect { cli_execute 'example' }.to raise_error(SystemExit)
|
27
|
+
output.should include('No stage specified. Please specify one of: development, production')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
28
31
|
it 'uses specified stage' do
|
29
32
|
cli_execute %w[production example]
|
30
|
-
config.
|
33
|
+
config.current_stage.should == 'production'
|
31
34
|
config.foo.should == 'baz'
|
32
35
|
end
|
36
|
+
|
37
|
+
it 'sets variables from options' do
|
38
|
+
cli_execute 'another_stage'
|
39
|
+
config.foo.should == 'bar'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'accepts default option' do
|
43
|
+
mock_config { stage :to_be_default, :default => true }
|
44
|
+
config.default_stage.should == :to_be_default
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with git' do
|
48
|
+
before do
|
49
|
+
mock_config { use_recipe :git }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'infers stage using local branch' do
|
53
|
+
config.stub(:local_branch) { 'master' }
|
54
|
+
cli_execute 'example'
|
55
|
+
config.current_stage.should == 'production'
|
56
|
+
config.branch.should == 'master'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'uses default state when local branch not matches' do
|
60
|
+
config.stub(:local_branch) { 'foo' }
|
61
|
+
cli_execute 'example'
|
62
|
+
config.current_stage.should == 'development'
|
63
|
+
config.branch.should == 'develop'
|
64
|
+
end
|
65
|
+
end
|
33
66
|
end
|
data/spec/passenger_spec.rb
CHANGED
@@ -13,12 +13,10 @@ describe 'passenger' do
|
|
13
13
|
cli_execute 'passenger:restart'
|
14
14
|
config.should have_run('touch /foo/bar/tmp/restart.txt')
|
15
15
|
end
|
16
|
-
end
|
17
16
|
|
18
|
-
|
19
|
-
it 'touches tmp/restart.txt' do
|
17
|
+
it 'is executed after deploy:restart' do
|
20
18
|
cli_execute 'deploy:restart'
|
21
|
-
config.should
|
19
|
+
config.should have_executed('deploy:restart', 'passenger:restart')
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'rails assets' do
|
4
|
+
before do
|
5
|
+
mock_config do
|
6
|
+
use_recipe :rails_assets
|
7
|
+
set :deploy_to, '/foo/bar'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'uses rails recipe' do
|
12
|
+
config.should be_using_recipe(:rails)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'deploy:assets:precompile' do
|
16
|
+
it 'runs precompile' do
|
17
|
+
cli_execute 'deploy:assets:precompile'
|
18
|
+
config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets rake assets:precompile')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'uses bundle command' do
|
22
|
+
mock_config { use_recipe :bundle }
|
23
|
+
cli_execute 'deploy:assets:precompile'
|
24
|
+
config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake assets:precompile')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'is invoked after deploy:update' do
|
28
|
+
cli_execute 'deploy:update'
|
29
|
+
config.should have_executed('deploy:update', 'deploy:assets:precompile')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'deploy:assets:clean' do
|
34
|
+
it 'runs clean' do
|
35
|
+
cli_execute 'deploy:assets:clean'
|
36
|
+
config.should have_run('cd /foo/bar && RAILS_ENV=production RAILS_GROUPS=assets rake assets:clean')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/rails_spec.rb
CHANGED
@@ -2,14 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'rails' do
|
4
4
|
before do
|
5
|
-
mock_config
|
5
|
+
mock_config do
|
6
|
+
use_recipe :rails
|
7
|
+
set :deploy_to, '/foo/bar'
|
8
|
+
end
|
6
9
|
end
|
7
10
|
|
8
11
|
describe 'deploy:migrate' do
|
9
|
-
before do
|
10
|
-
mock_config { set :deploy_to, '/foo/bar' }
|
11
|
-
end
|
12
|
-
|
13
12
|
it 'runs rake db:migrate' do
|
14
13
|
cli_execute 'deploy:migrate'
|
15
14
|
config.should have_run('cd /foo/bar && RAILS_ENV=production rake db:migrate')
|
@@ -24,10 +23,8 @@ describe 'rails' do
|
|
24
23
|
|
25
24
|
describe 'deploy:migrations' do
|
26
25
|
it 'runs update, migrate and restart' do
|
27
|
-
config.namespaces[:deploy].should_receive(:update)
|
28
|
-
config.namespaces[:deploy].should_receive(:migrate)
|
29
|
-
config.namespaces[:deploy].should_receive(:restart)
|
30
26
|
cli_execute 'deploy:migrations'
|
27
|
+
config.should have_executed('deploy:update', 'deploy:migrate', 'deploy:restart')
|
31
28
|
end
|
32
29
|
end
|
33
30
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,24 @@
|
|
1
|
-
require 'capistrano'
|
2
|
-
require 'capistrano/cli'
|
3
1
|
require 'capistrano-deploy'
|
2
|
+
require 'capistrano/cli'
|
4
3
|
|
5
4
|
module CapistranoDeploy
|
6
5
|
module Spec
|
7
6
|
module ConfigurationExtension
|
8
7
|
def run(cmd, options={}, &block)
|
9
|
-
|
8
|
+
runned_commands[cmd] = {:options => options, :block => block}
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute_task(task)
|
12
|
+
executed_tasks << task.fully_qualified_name
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def runned_commands
|
17
|
+
@runned_commands ||= {}
|
10
18
|
end
|
11
19
|
|
12
|
-
def
|
13
|
-
@
|
20
|
+
def executed_tasks
|
21
|
+
@executed_tasks ||= []
|
14
22
|
end
|
15
23
|
end
|
16
24
|
|
@@ -31,16 +39,30 @@ module CapistranoDeploy
|
|
31
39
|
|
32
40
|
def cli_execute(*args)
|
33
41
|
config = @config
|
34
|
-
cli = Capistrano::CLI.parse(args.flatten)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
42
|
+
cli = Capistrano::CLI.parse(args.flatten)
|
43
|
+
cli.instance_eval do
|
44
|
+
(class << self; self end).send(:define_method, :instantiate_configuration) do |options|
|
45
|
+
config
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
42
49
|
cli.execute!
|
43
50
|
end
|
51
|
+
|
52
|
+
def with_stderr
|
53
|
+
original, $stderr = $stderr, StringIO.new
|
54
|
+
output = Object.new
|
55
|
+
class << output
|
56
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$|^instance_eval$/ }
|
57
|
+
end
|
58
|
+
def output.method_missing(*args, &block)
|
59
|
+
($stderr.rewind && $stderr.read).__send__(*args, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
yield output
|
63
|
+
ensure
|
64
|
+
$stderr = original
|
65
|
+
end
|
44
66
|
end
|
45
67
|
|
46
68
|
module Matchers
|
@@ -48,11 +70,26 @@ module CapistranoDeploy
|
|
48
70
|
|
49
71
|
define :have_run do |cmd|
|
50
72
|
match do |configuration|
|
51
|
-
configuration.
|
73
|
+
configuration.runned_commands[cmd]
|
74
|
+
end
|
75
|
+
|
76
|
+
failure_message_for_should do |configuration|
|
77
|
+
"expected configuration to run #{cmd}, but it wasn't found in #{configuration.runned_commands.keys}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
define :have_executed do |*tasks|
|
82
|
+
match do |configuration|
|
83
|
+
expected = tasks.dup
|
84
|
+
configuration.executed_tasks.each do |actual|
|
85
|
+
expected.shift if actual == expected.first
|
86
|
+
end
|
87
|
+
|
88
|
+
expected.empty?
|
52
89
|
end
|
53
90
|
|
54
91
|
failure_message_for_should do |configuration|
|
55
|
-
"expected configuration to
|
92
|
+
"expected configuration to execute #{tasks}, but it executed #{configuration.executed_tasks.keys}"
|
56
93
|
end
|
57
94
|
end
|
58
95
|
end
|
data/spec/unicorn_spec.rb
CHANGED
@@ -15,17 +15,17 @@ describe 'unicorn' do
|
|
15
15
|
mock_config { set :unicorn_pid, '/foo.pid' }
|
16
16
|
end
|
17
17
|
|
18
|
-
it '
|
18
|
+
it 'sends HUP' do
|
19
19
|
cli_execute 'unicorn:reload'
|
20
20
|
config.should have_run('kill -HUP /foo.pid')
|
21
21
|
end
|
22
22
|
|
23
|
-
it '
|
23
|
+
it 'sends QUIT' do
|
24
24
|
cli_execute 'unicorn:stop'
|
25
25
|
config.should have_run('kill -QUIT /foo.pid')
|
26
26
|
end
|
27
27
|
|
28
|
-
it '
|
28
|
+
it 'sends USR2' do
|
29
29
|
cli_execute 'unicorn:reexec'
|
30
30
|
config.should have_run('kill -USR2 /foo.pid')
|
31
31
|
end
|
data/spec/whenever_spec.rb
CHANGED
@@ -17,9 +17,32 @@ describe 'whenever' do
|
|
17
17
|
it 'default to application with stage when using multistage' do
|
18
18
|
mock_config do
|
19
19
|
use_recipe :multistage
|
20
|
-
set :
|
20
|
+
set :current_stage, 'bar'
|
21
21
|
end
|
22
22
|
config.whenever_identifier.should == 'foo_bar'
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
describe 'whenever_cmd' do
|
27
|
+
it 'has default value' do
|
28
|
+
config.whenever_cmd.should == 'whenever'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'respects bundle recipe' do
|
32
|
+
mock_config { use_recipe :bundle }
|
33
|
+
config.whenever_cmd.should == 'bundle exec whenever'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'whenever:update_crontab' do
|
38
|
+
it 'runs command' do
|
39
|
+
mock_config do
|
40
|
+
set :deploy_to, '/foo/bar'
|
41
|
+
set :whenever_cmd, 'wc'
|
42
|
+
set :whenever_identifier, 'wi'
|
43
|
+
end
|
44
|
+
cli_execute 'whenever:update_crontab'
|
45
|
+
config.should have_run('cd /foo/bar && wc --update-crontab wi')
|
46
|
+
end
|
47
|
+
end
|
25
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: capistrano
|
16
|
-
requirement: &
|
16
|
+
requirement: &15867460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 2.9.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *15867460
|
25
25
|
description:
|
26
26
|
email:
|
27
27
|
- just.lest@gmail.com
|
@@ -31,25 +31,30 @@ extra_rdoc_files: []
|
|
31
31
|
files:
|
32
32
|
- .gitignore
|
33
33
|
- .rspec
|
34
|
+
- .travis.yml
|
34
35
|
- Gemfile
|
35
36
|
- Gemfile.lock
|
37
|
+
- MIT-LICENSE
|
36
38
|
- README.md
|
37
39
|
- Rakefile
|
38
40
|
- capistrano-deploy.gemspec
|
39
41
|
- lib/capistrano-deploy.rb
|
40
42
|
- lib/capistrano-deploy/bundle.rb
|
41
|
-
- lib/capistrano-deploy/
|
43
|
+
- lib/capistrano-deploy/bundler.rb
|
42
44
|
- lib/capistrano-deploy/git.rb
|
43
45
|
- lib/capistrano-deploy/multistage.rb
|
44
46
|
- lib/capistrano-deploy/passenger.rb
|
45
47
|
- lib/capistrano-deploy/rails.rb
|
48
|
+
- lib/capistrano-deploy/rails_assets.rb
|
46
49
|
- lib/capistrano-deploy/rvm.rb
|
47
50
|
- lib/capistrano-deploy/unicorn.rb
|
48
51
|
- lib/capistrano-deploy/whenever.rb
|
52
|
+
- spec/bundle_spec.rb
|
49
53
|
- spec/deploy_spec.rb
|
50
54
|
- spec/git_spec.rb
|
51
55
|
- spec/multistage_spec.rb
|
52
56
|
- spec/passenger_spec.rb
|
57
|
+
- spec/rails_assets_spec.rb
|
53
58
|
- spec/rails_spec.rb
|
54
59
|
- spec/spec_helper.rb
|
55
60
|
- spec/unicorn_spec.rb
|
@@ -68,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
73
|
version: '0'
|
69
74
|
segments:
|
70
75
|
- 0
|
71
|
-
hash:
|
76
|
+
hash: -3624144912279790165
|
72
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
78
|
none: false
|
74
79
|
requirements:
|
@@ -77,18 +82,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
82
|
version: '0'
|
78
83
|
segments:
|
79
84
|
- 0
|
80
|
-
hash:
|
85
|
+
hash: -3624144912279790165
|
81
86
|
requirements: []
|
82
87
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.8.
|
88
|
+
rubygems_version: 1.8.15
|
84
89
|
signing_key:
|
85
90
|
specification_version: 3
|
86
91
|
summary: Capistrano deploy recipes
|
87
92
|
test_files:
|
93
|
+
- spec/bundle_spec.rb
|
88
94
|
- spec/deploy_spec.rb
|
89
95
|
- spec/git_spec.rb
|
90
96
|
- spec/multistage_spec.rb
|
91
97
|
- spec/passenger_spec.rb
|
98
|
+
- spec/rails_assets_spec.rb
|
92
99
|
- spec/rails_spec.rb
|
93
100
|
- spec/spec_helper.rb
|
94
101
|
- spec/unicorn_spec.rb
|
@@ -1,65 +0,0 @@
|
|
1
|
-
warn "[DEPRECATION] require 'capistrano-deploy/deploy' is deprecated. Please use require 'capistrano-deploy' and use_recipes :git, :rails instead."
|
2
|
-
|
3
|
-
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
-
ssh_options[:forward_agent] = true
|
5
|
-
|
6
|
-
set(:application) { repository.slice(/[^\/:]+?(?=\.git$)/) }
|
7
|
-
set(:repository) { abort "Please specify repository, set :repository, 'foo'" }
|
8
|
-
set(:deploy_to) { abort "Please specify deploy directory, set :deploy_to, '/deploy/to/path'" }
|
9
|
-
|
10
|
-
set :branch, 'master'
|
11
|
-
|
12
|
-
set :enable_submodules, false
|
13
|
-
|
14
|
-
set(:current_revision) { capture("cd #{deploy_to} && git rev-parse HEAD").chomp }
|
15
|
-
|
16
|
-
namespace :deploy do
|
17
|
-
desc 'Deploy'
|
18
|
-
task :default do
|
19
|
-
update
|
20
|
-
restart
|
21
|
-
end
|
22
|
-
|
23
|
-
desc 'Deploy & migrate'
|
24
|
-
task :migrations do
|
25
|
-
update_code
|
26
|
-
migrate
|
27
|
-
restart
|
28
|
-
end
|
29
|
-
|
30
|
-
desc 'Setup'
|
31
|
-
task :setup, :except => {:no_release => true} do
|
32
|
-
run "mkdir -p `dirname #{deploy_to}` && git clone --no-checkout #{repository} #{deploy_to}"
|
33
|
-
update_code
|
34
|
-
end
|
35
|
-
|
36
|
-
desc 'Update'
|
37
|
-
task :update do
|
38
|
-
update_code
|
39
|
-
end
|
40
|
-
|
41
|
-
desc 'Update the deployed code'
|
42
|
-
task :update_code, :except => {:no_release => true} do
|
43
|
-
command = ["cd #{deploy_to}", 'git fetch origin', "git reset --hard origin/#{branch}"]
|
44
|
-
command += ['git submodule init', 'git submodule -q sync', 'git submodule -q update'] if enable_submodules
|
45
|
-
run command.join(' && ')
|
46
|
-
end
|
47
|
-
|
48
|
-
desc 'Run migrations'
|
49
|
-
task :migrate, :roles => :db, :only => {:primary => true} do
|
50
|
-
rake = fetch(:rake, 'rake')
|
51
|
-
rails_env = fetch(:rails_env, 'production')
|
52
|
-
run "cd #{deploy_to} && RAILS_ENV=#{rails_env} #{rake} db:migrate"
|
53
|
-
end
|
54
|
-
|
55
|
-
desc 'Restart'
|
56
|
-
task :restart do
|
57
|
-
# nothing
|
58
|
-
end
|
59
|
-
|
60
|
-
desc 'Show pending commits'
|
61
|
-
task :pending do
|
62
|
-
system("git log --pretty=medium --stat #{current_revision}..origin/#{branch}")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|