capistrano 3.0.0.pre14 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +1 -1
- data/bin/cap +1 -1
- data/capistrano.gemspec +3 -0
- data/features/deploy.feature +52 -0
- data/features/installation.feature +16 -0
- data/features/remote_file_task.feature +14 -0
- data/features/step_definitions/assertions.rb +90 -0
- data/features/step_definitions/cap_commands.rb +8 -0
- data/features/step_definitions/setup.rb +25 -0
- data/features/support/env.rb +12 -0
- data/features/support/remote_command_helpers.rb +20 -0
- data/lib/Capfile +1 -0
- data/lib/capistrano.rb +0 -14
- data/lib/capistrano/all.rb +16 -0
- data/lib/capistrano/application.rb +1 -10
- data/lib/capistrano/configuration.rb +4 -0
- data/lib/capistrano/configuration/server.rb +44 -6
- data/lib/capistrano/configuration/servers.rb +14 -51
- data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
- data/lib/capistrano/defaults.rb +0 -8
- data/lib/capistrano/dsl.rb +1 -1
- data/lib/capistrano/dsl/env.rb +6 -2
- data/lib/capistrano/dsl/paths.rb +7 -4
- data/lib/capistrano/dsl/task_enhancements.rb +38 -0
- data/lib/capistrano/hg.rb +1 -0
- data/lib/capistrano/i18n.rb +1 -1
- data/lib/capistrano/setup.rb +7 -3
- data/lib/capistrano/tasks/deploy.rake +39 -9
- data/lib/capistrano/tasks/framework.rake +0 -2
- data/lib/capistrano/tasks/git.rake +3 -6
- data/lib/capistrano/tasks/hg.rake +39 -0
- data/lib/capistrano/templates/Capfile +2 -23
- data/lib/capistrano/templates/deploy.rb.erb +23 -0
- data/lib/capistrano/templates/stage.rb.erb +1 -1
- data/lib/capistrano/version.rb +1 -1
- data/spec/integration/dsl_spec.rb +71 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +69 -0
- data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +46 -9
- data/spec/lib/capistrano/configuration_spec.rb +11 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/support/.gitignore +1 -0
- data/spec/support/Vagrantfile +13 -0
- data/spec/support/tasks/database.cap +11 -0
- data/spec/support/test_app.rb +55 -6
- metadata +74 -16
- data/lib/capistrano/bundler.rb +0 -1
- data/lib/capistrano/tasks/bundler.rake +0 -13
- data/spec/integration/deploy_finalize_spec.rb +0 -34
- data/spec/integration/deploy_finished_spec.rb +0 -36
- data/spec/integration/deploy_started_spec.rb +0 -74
- data/spec/integration/deploy_update_spec.rb +0 -45
- data/spec/integration/installation_spec.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e84be755bb1beb1fa002d555a2a237a569fe0b0
|
4
|
+
data.tar.gz: 2fdcff3917f21ed061bc94fa74d09fb06e4b8bd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d330918070791f930fc5254574f633ec354b87ebd2b194b16392771f1d135c1d1352f412ca915e8c194b8776fa0b820e023f88829782807bb2c4d41cf37981d
|
7
|
+
data.tar.gz: bd9b0c4d70a9b420decc32592d7fd5d59e93d40e01558318e5f969dfb5add69ccb813a10a3518224940d8da6f40f1d6e30699e072ada18b97925a08aaa6426a5
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,48 @@
|
|
2
2
|
|
3
3
|
Reverse Chronological Order:
|
4
4
|
|
5
|
+
## `3.0.0`
|
6
|
+
|
7
|
+
If you are coming here to wonder why your Capfile doesn't work anymore, please
|
8
|
+
vendor lock your Capistrano at 2.5.x, whichever version was working for you
|
9
|
+
until today.
|
10
|
+
|
11
|
+
Capistrano 3 is a ground-up rewrite with modularity, stability, speed and
|
12
|
+
future proofing in mind. It's a big change, but now the code is 10x smaller,
|
13
|
+
runs faster, is easier to read, and quicker to extend. In the reduction we've
|
14
|
+
come up with a great gem based modular system for plugins and we're really
|
15
|
+
proud of this release.
|
16
|
+
|
17
|
+
The 3.0.0 release contains 38 patches from the following amazing people:
|
18
|
+
|
19
|
+
* Tom `seenmyfate` Clements: more than 28 patches including cucumber integration tests! Not to
|
20
|
+
mention Rails asset pipeline code, and bundler integrations.
|
21
|
+
* Lee Hambley: Small changes around compatibility and log formatting
|
22
|
+
* Kir Shatrov: for improvements in the core to make it easier to write extensions, for
|
23
|
+
improving documentation, and for effectively building the chruby, rvm and rbenv integrations.
|
24
|
+
* Michael Nikitochkin: Fixing a bug around linked files and directories.
|
25
|
+
* Jack Thorne: for improvements to the default `Capfile` to fix some bad example syntax.
|
26
|
+
* Erik Hetzner: for (what looks like great) work on the Mercurial (Hg) support. The Hg and Git
|
27
|
+
source control mechanisms do not work the same way, but rather lean on the strengths of the
|
28
|
+
underlying tools.
|
29
|
+
|
30
|
+
(If I missed anyone, I'm sorry, your contributions have been awesome)
|
31
|
+
|
32
|
+
The 2.x branch of code is now no longer maintained. Towards the end of it's
|
33
|
+
useful life there were an increasing number of features and pieces of code
|
34
|
+
which didn't make sense for certain groups of people, in certain situations,
|
35
|
+
leading a to a ping-pong tennis effect with pull requests every few weeks
|
36
|
+
"fixing" a use-case which had already been "fixed" shortly before. As many of
|
37
|
+
the use-cases are outside the scope of the testing environments I (and by
|
38
|
+
extension the trusted contributors and IRC regulars) were able to test for.
|
39
|
+
|
40
|
+
There's a more extensive post about my failure to be able to keep up with the
|
41
|
+
demands of maintaining v2 whilst trying to build something which is appropriate
|
42
|
+
for the current landscape. If you are affected by the unsupported 2 branch,
|
43
|
+
please contact me (Lee Hambley) to dicsuss how my company can help support you.
|
44
|
+
Otherwise, please try v3, we're sure you'll like it, and the code is designed
|
45
|
+
to be so simple that anyone can work on it.
|
46
|
+
|
5
47
|
## `3.0.0.pre14`
|
6
48
|
|
7
49
|
* Thanks to numerous contributors, in particular (@teohm) for a series of improvements.
|
data/README.md
CHANGED
data/bin/cap
CHANGED
data/capistrano.gemspec
CHANGED
@@ -28,5 +28,8 @@ Gem::Specification.new do |gem|
|
|
28
28
|
|
29
29
|
gem.add_development_dependency 'rspec'
|
30
30
|
gem.add_development_dependency 'mocha'
|
31
|
+
gem.add_development_dependency 'vagrant', '~> 1.0.7'
|
32
|
+
gem.add_development_dependency 'kuroko'
|
33
|
+
gem.add_development_dependency 'cucumber'
|
31
34
|
|
32
35
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Feature: Deploy
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
And servers with the roles app and web
|
6
|
+
|
7
|
+
Scenario: Creating the repo
|
8
|
+
When I run cap "git:check"
|
9
|
+
Then references in the remote repo are listed
|
10
|
+
|
11
|
+
Scenario: Creating the directory structure
|
12
|
+
When I run cap "deploy:check:directories"
|
13
|
+
Then the shared path is created
|
14
|
+
And the releases path is created
|
15
|
+
|
16
|
+
Scenario: Creating linked directories
|
17
|
+
When I run cap "deploy:check:linked_dirs"
|
18
|
+
Then directories in :linked_dirs are created in shared
|
19
|
+
|
20
|
+
Scenario: Creating linked directories for linked files
|
21
|
+
When I run cap "deploy:check:make_linked_dirs"
|
22
|
+
Then directories referenced in :linked_files are created in shared
|
23
|
+
|
24
|
+
Scenario: Checking linked files - missing file
|
25
|
+
Given a required file
|
26
|
+
But the file does not exist
|
27
|
+
When I run cap "deploy:check:linked_files"
|
28
|
+
Then the task will exit
|
29
|
+
|
30
|
+
Scenario: Checking linked files - file exists
|
31
|
+
Given a required file
|
32
|
+
And that file exists
|
33
|
+
When I run cap "deploy:check:linked_files"
|
34
|
+
Then the task will be successful
|
35
|
+
|
36
|
+
Scenario: Creating a release
|
37
|
+
When I run cap "git:create_release" as part of a release
|
38
|
+
Then the repo is cloned
|
39
|
+
And the release is created
|
40
|
+
|
41
|
+
Scenario: Symlink linked files
|
42
|
+
When I run cap "deploy:symlink:linked_files" as part of a release
|
43
|
+
Then file symlinks are created in the new release
|
44
|
+
|
45
|
+
Scenario: Symlink linked dirs
|
46
|
+
When I run cap "deploy:symlink:linked_dirs" as part of a release
|
47
|
+
Then directory symlinks are created in the new release
|
48
|
+
|
49
|
+
Scenario: Publishing
|
50
|
+
When I run cap "deploy:symlink:release"
|
51
|
+
Then the current directory will be a symlink to the release
|
52
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Installation
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
|
6
|
+
Scenario: With default stages
|
7
|
+
When I run cap "install"
|
8
|
+
Then the deploy.rb file is created
|
9
|
+
And the default stage files are created
|
10
|
+
And the tasks folder is created
|
11
|
+
|
12
|
+
Scenario: With specified stages
|
13
|
+
When I run cap "install STAGES=qa,production"
|
14
|
+
Then the deploy.rb file is created
|
15
|
+
And the specified stage files are created
|
16
|
+
And the tasks folder is created
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Remote file task
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
And a custom task to generate a file
|
6
|
+
And servers with the roles app and web
|
7
|
+
|
8
|
+
Scenario: Where the file does not exist
|
9
|
+
When I run cap "deploy:check:linked_files"
|
10
|
+
Then it creates the file with the remote_task prerequisite
|
11
|
+
|
12
|
+
Scenario: Where the file already exists
|
13
|
+
When I run cap "deploy:check:linked_files"
|
14
|
+
Then it will not recreate the file
|
@@ -0,0 +1,90 @@
|
|
1
|
+
Then(/^references in the remote repo are listed$/) do
|
2
|
+
end
|
3
|
+
|
4
|
+
Then(/^the shared path is created$/) do
|
5
|
+
run_vagrant_command(test_dir_exists(TestApp.shared_path))
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^the releases path is created$/) do
|
9
|
+
run_vagrant_command(test_dir_exists(TestApp.releases_path))
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^directories in :linked_dirs are created in shared$/) do
|
13
|
+
TestApp.linked_dirs.each do |dir|
|
14
|
+
run_vagrant_command(test_dir_exists(TestApp.shared_path.join(dir)))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Then(/^directories referenced in :linked_files are created in shared$/) do
|
19
|
+
dirs = TestApp.linked_files.map { |path| TestApp.shared_path.join(path).dirname }
|
20
|
+
dirs.each do | dir|
|
21
|
+
run_vagrant_command(test_dir_exists(dir))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Then(/^the task will be successful$/) do
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
Then(/^the task will exit$/) do
|
30
|
+
end
|
31
|
+
|
32
|
+
Then(/^the repo is cloned$/) do
|
33
|
+
run_vagrant_command(test_dir_exists(TestApp.repo_path))
|
34
|
+
end
|
35
|
+
|
36
|
+
Then(/^the release is created$/) do
|
37
|
+
run_vagrant_command("ls -g #{TestApp.releases_path}")
|
38
|
+
end
|
39
|
+
|
40
|
+
Then(/^file symlinks are created in the new release$/) do
|
41
|
+
pending
|
42
|
+
TestApp.linked_files.each do |file|
|
43
|
+
run_vagrant_command(test_symlink_exists(TestApp.release_path.join(file)))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Then(/^directory symlinks are created in the new release$/) do
|
48
|
+
pending
|
49
|
+
TestApp.linked_dirs.each do |dir|
|
50
|
+
run_vagrant_command(test_symlink_exists(TestApp.release_path.join(dir)))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Then(/^the current directory will be a symlink to the release$/) do
|
55
|
+
run_vagrant_command(test_symlink_exists(TestApp.current_path))
|
56
|
+
end
|
57
|
+
|
58
|
+
Then(/^the deploy\.rb file is created$/) do
|
59
|
+
file = TestApp.test_app_path.join('config/deploy.rb')
|
60
|
+
expect(File.exists?(file)).to be_true
|
61
|
+
end
|
62
|
+
|
63
|
+
Then(/^the default stage files are created$/) do
|
64
|
+
staging = TestApp.test_app_path.join('config/deploy/staging.rb')
|
65
|
+
production = TestApp.test_app_path.join('config/deploy/production.rb')
|
66
|
+
expect(File.exists?(staging)).to be_true
|
67
|
+
expect(File.exists?(production)).to be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
Then(/^the tasks folder is created$/) do
|
71
|
+
path = TestApp.test_app_path.join('lib/capistrano/tasks')
|
72
|
+
expect(Dir.exists?(path)).to be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
Then(/^the specified stage files are created$/) do
|
76
|
+
qa = TestApp.test_app_path.join('config/deploy/qa.rb')
|
77
|
+
production = TestApp.test_app_path.join('config/deploy/production.rb')
|
78
|
+
expect(File.exists?(qa)).to be_true
|
79
|
+
expect(File.exists?(production)).to be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
Then(/^it creates the file with the remote_task prerequisite$/) do
|
83
|
+
TestApp.linked_files.each do |file|
|
84
|
+
run_vagrant_command(test_file_exists(TestApp.shared_path.join(file)))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Then(/^it will not recreate the file$/) do
|
89
|
+
#
|
90
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Given(/^a test app with the default configuration$/) do
|
2
|
+
TestApp.install
|
3
|
+
end
|
4
|
+
|
5
|
+
Given(/^servers with the roles app and web$/) do
|
6
|
+
vagrant_cli_command('up')
|
7
|
+
end
|
8
|
+
|
9
|
+
Given(/^a required file$/) do
|
10
|
+
end
|
11
|
+
|
12
|
+
Given(/^that file exists$/) do
|
13
|
+
run_vagrant_command("touch #{TestApp.linked_file}")
|
14
|
+
end
|
15
|
+
|
16
|
+
Given(/^the file does not exist$/) do
|
17
|
+
pending
|
18
|
+
file = TestApp.linked_file
|
19
|
+
run_vagrant_command("[ -f #{file} ] && rm #{file}")
|
20
|
+
end
|
21
|
+
|
22
|
+
Given(/^a custom task to generate a file$/) do
|
23
|
+
TestApp.copy_task_to_test_app('spec/support/tasks/database.cap')
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'kuroko'
|
2
|
+
|
3
|
+
project_root = File.expand_path('../../../', __FILE__)
|
4
|
+
vagrant_root = File.join(project_root, 'spec/support')
|
5
|
+
|
6
|
+
Kuroko.configure do |config|
|
7
|
+
config.vagrant_root = 'spec/support'
|
8
|
+
end
|
9
|
+
|
10
|
+
puts vagrant_root.inspect
|
11
|
+
|
12
|
+
require_relative '../../spec/support/test_app'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RemoteCommandHelpers
|
2
|
+
|
3
|
+
def test_dir_exists(path)
|
4
|
+
exists?('d', path)
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_symlink_exists(path)
|
8
|
+
exists?('L', path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_file_exists(path)
|
12
|
+
exists?('f', path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def exists?(type, path)
|
16
|
+
%{[ -#{type} "#{path}" ] && echo "#{path} exists." || echo "Error: #{path} does not exist."}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
World(RemoteCommandHelpers)
|
data/lib/Capfile
CHANGED
data/lib/capistrano.rb
CHANGED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'sshkit'
|
3
|
-
|
4
|
-
Rake.application.options.trace = true
|
5
|
-
|
6
|
-
require 'capistrano/version'
|
7
|
-
require 'capistrano/version_validator'
|
8
|
-
require 'capistrano/i18n'
|
9
|
-
require 'capistrano/dsl'
|
10
|
-
require 'capistrano/application'
|
11
|
-
require 'capistrano/configuration'
|
12
|
-
|
13
|
-
module Capistrano
|
14
|
-
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'sshkit'
|
3
|
+
require 'sshkit/dsl'
|
4
|
+
|
5
|
+
Rake.application.options.trace = true
|
6
|
+
|
7
|
+
require 'capistrano/version'
|
8
|
+
require 'capistrano/version_validator'
|
9
|
+
require 'capistrano/i18n'
|
10
|
+
require 'capistrano/dsl'
|
11
|
+
require 'capistrano/application'
|
12
|
+
require 'capistrano/configuration'
|
13
|
+
|
14
|
+
module Capistrano
|
15
|
+
|
16
|
+
end
|
@@ -26,7 +26,7 @@ module Capistrano
|
|
26
26
|
if tasks_without_stage_dependency.include?(@top_level_tasks.first)
|
27
27
|
@top_level_tasks
|
28
28
|
else
|
29
|
-
@top_level_tasks.unshift(
|
29
|
+
@top_level_tasks.unshift(ensure_stage)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -37,15 +37,6 @@ module Capistrano
|
|
37
37
|
File.expand_path(File.join(File.dirname(__FILE__),'..','Capfile'))
|
38
38
|
end
|
39
39
|
|
40
|
-
def tasks_without_stage_dependency
|
41
|
-
defined_stages = Dir['config/deploy/*.rb'].map { |f| File.basename(f, '.rb') }
|
42
|
-
defined_stages + default_tasks
|
43
|
-
end
|
44
|
-
|
45
|
-
def default_tasks
|
46
|
-
%w{install}
|
47
|
-
end
|
48
|
-
|
49
40
|
def version
|
50
41
|
['--version', '-V',
|
51
42
|
"Display the program version.",
|
@@ -22,6 +22,11 @@ module Capistrano
|
|
22
22
|
hostname == Server.new(host).hostname
|
23
23
|
end
|
24
24
|
|
25
|
+
def select?(options)
|
26
|
+
selector = Selector.new(options)
|
27
|
+
selector.call(self)
|
28
|
+
end
|
29
|
+
|
25
30
|
def primary
|
26
31
|
self if fetch(:primary)
|
27
32
|
end
|
@@ -41,6 +46,20 @@ module Capistrano
|
|
41
46
|
alias_method :netssh_options_without_options, :netssh_options
|
42
47
|
alias_method :netssh_options, :netssh_options_with_options
|
43
48
|
|
49
|
+
def roles_array
|
50
|
+
roles.to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def add_property(key, value)
|
56
|
+
if respond_to?("#{key}=")
|
57
|
+
send("#{key}=", value)
|
58
|
+
else
|
59
|
+
set(key, value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
44
63
|
class Properties
|
45
64
|
|
46
65
|
def initialize
|
@@ -79,15 +98,34 @@ module Capistrano
|
|
79
98
|
|
80
99
|
end
|
81
100
|
|
101
|
+
class Selector
|
102
|
+
def initialize(options)
|
103
|
+
@options = options
|
104
|
+
end
|
82
105
|
|
83
|
-
|
106
|
+
def callable
|
107
|
+
if key.respond_to?(:call)
|
108
|
+
key
|
109
|
+
else
|
110
|
+
->(server) { server.fetch(key) }
|
111
|
+
end
|
112
|
+
end
|
84
113
|
|
85
|
-
|
86
|
-
|
87
|
-
send("#{key}=", value)
|
88
|
-
else
|
89
|
-
set(key, value)
|
114
|
+
def call(server)
|
115
|
+
callable.call(server)
|
90
116
|
end
|
117
|
+
|
118
|
+
private
|
119
|
+
attr_reader :options
|
120
|
+
|
121
|
+
def key
|
122
|
+
options[:filter] || options[:select] || all
|
123
|
+
end
|
124
|
+
|
125
|
+
def all
|
126
|
+
->(server) { :all }
|
127
|
+
end
|
128
|
+
|
91
129
|
end
|
92
130
|
|
93
131
|
end
|