capistrano 3.8.2 → 3.9.0
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 +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +17 -1
- data/CONTRIBUTING.md +2 -0
- data/DEVELOPMENT.md +2 -3
- data/README.md +3 -1
- data/features/deploy.feature +18 -0
- data/features/step_definitions/assertions.rb +27 -1
- data/features/step_definitions/cap_commands.rb +6 -0
- data/features/step_definitions/setup.rb +31 -1
- data/features/support/remote_command_helpers.rb +4 -0
- data/features/support/vagrant_helpers.rb +9 -8
- data/lib/capistrano/dsl.rb +7 -1
- data/lib/capistrano/i18n.rb +1 -1
- data/lib/capistrano/tasks/deploy.rake +7 -5
- data/lib/capistrano/version.rb +1 -1
- data/spec/lib/capistrano/dsl_spec.rb +47 -6
- data/spec/support/test_app.rb +4 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4ae57e87cafad9fe7cb1307d847f5f3bd9d7ccb
|
4
|
+
data.tar.gz: e6ea828e10e6863b07c9fcd685a334464a3a3890
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49fd63f868fdc87cefd58e047dc22c2b05cd95211a7a99080a010f627c3f32944539a16876ade7496257d4a8b71e18fc099a57ec126abf3f2efa7d2991d36c41
|
7
|
+
data.tar.gz: 35064cfd5c3da3a39e8ca044aa1eae03b8b0fbbea3c22a08fb08d5c2755b1fe18f7be8f2e7bccc431214d166f0d953e5c112d026b818a462105761528f3478cc
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -16,10 +16,26 @@ gem "capistrano", :github => "capistrano/capistrano"
|
|
16
16
|
|
17
17
|
## master
|
18
18
|
|
19
|
-
https://github.com/capistrano/capistrano/compare/v3.
|
19
|
+
https://github.com/capistrano/capistrano/compare/v3.9.0...HEAD
|
20
20
|
|
21
21
|
* Your contribution here!
|
22
22
|
|
23
|
+
## `3.9.0` (2017-07-28)
|
24
|
+
|
25
|
+
https://github.com/capistrano/capistrano/compare/v3.8.2...v3.9.0
|
26
|
+
|
27
|
+
### Breaking changes:
|
28
|
+
|
29
|
+
* None
|
30
|
+
|
31
|
+
### New features:
|
32
|
+
|
33
|
+
* [#1911](https://github.com/capistrano/capistrano/pull/1911): Add Capistrano::DSL#invoke! for repetetive tasks
|
34
|
+
|
35
|
+
### Fixes:
|
36
|
+
|
37
|
+
* [#1899](https://github.com/capistrano/capistrano/pull/1899): Updated `deploy:cleanup` to continue rotating the releases and skip the invalid directory names instead of skipping the whole rotation of releases. The warning message has changed slightly due to the change of behavior.
|
38
|
+
|
23
39
|
## `3.8.2` (2017-06-16)
|
24
40
|
|
25
41
|
https://github.com/capistrano/capistrano/compare/v3.8.1...v3.8.2
|
data/CONTRIBUTING.md
CHANGED
@@ -41,6 +41,8 @@ Also include in your report:
|
|
41
41
|
|
42
42
|
If you are an experienced Ruby programmer, take a few minutes to get the Capistrano test suite running (see [DEVELOPMENT.md][]), and do what you can to get a test case written that fails. *This will be a huge help!*
|
43
43
|
|
44
|
+
If you think you may have discovered a security vulnerability in Capistrano, do not open a GitHub issue. Instead, please send a report to <security@capistranorb.com>.
|
45
|
+
|
44
46
|
## Requesting new features or improvements
|
45
47
|
|
46
48
|
Capistrano continues to improve thanks to people like you! Feel free to open a GitHub issue for any or all of these ideas:
|
data/DEVELOPMENT.md
CHANGED
@@ -28,11 +28,10 @@ Capistrano is a Ruby project, so we expect you to have a functioning Ruby enviro
|
|
28
28
|
|
29
29
|
Make sure to install:
|
30
30
|
|
31
|
-
* [Bundler](https://bundler.io/)
|
31
|
+
* [Bundler](https://bundler.io/)
|
32
32
|
* [Vagrant](https://www.vagrantup.com/)
|
33
33
|
* [VirtualBox](https://www.virtualbox.org/wiki/Downloads) (or another [Vagrant-supported](https://docs.vagrantup.com/v2/getting-started/providers.html) VM host)
|
34
34
|
|
35
|
-
*Note: As of this writing (December 2015), Vagrant does not work with Bundler > 1.10.5. If you have multiple versions of Bundler installed, use the special underscore command-line argument to force a compatible version, like this: `bundle _1.10.5_ exec rake features`.*
|
36
35
|
|
37
36
|
### Running tests
|
38
37
|
|
@@ -45,7 +44,7 @@ $ bundle install
|
|
45
44
|
# Run the RSpec suite
|
46
45
|
$ bundle exec rake spec
|
47
46
|
|
48
|
-
# Run the Cucumber suite
|
47
|
+
# Run the Cucumber suite
|
49
48
|
$ bundle exec rake features
|
50
49
|
|
51
50
|
# Run the Cucumber suite and leave the VM running (faster for subsequent runs)
|
data/README.md
CHANGED
@@ -103,7 +103,7 @@ Add Capistrano to your project's Gemfile:
|
|
103
103
|
|
104
104
|
``` ruby
|
105
105
|
group :development do
|
106
|
-
gem "capistrano", "~> 3.
|
106
|
+
gem "capistrano", "~> 3.9"
|
107
107
|
end
|
108
108
|
```
|
109
109
|
|
@@ -186,6 +186,8 @@ Related GitHub repositories:
|
|
186
186
|
|
187
187
|
GitHub issues are for bug reports and feature requests. Please refer to the [CONTRIBUTING](CONTRIBUTING.md) document for guidelines on submitting GitHub issues.
|
188
188
|
|
189
|
+
If you think you may have discovered a security vulnerability in Capistrano, do not open a GitHub issue. Instead, please send a report to <security@capistranorb.com>.
|
190
|
+
|
189
191
|
## How to contribute
|
190
192
|
|
191
193
|
Contributions to Capistrano, in the form of code, documentation or idea, are gladly accepted. Read the [DEVELOPMENT](DEVELOPMENT.md) document to learn how to hack on Capistrano's code, run the tests, and contribute your first pull request.
|
data/features/deploy.feature
CHANGED
@@ -52,3 +52,21 @@ Feature: Deploy
|
|
52
52
|
When I run cap "deploy:symlink:release"
|
53
53
|
Then the current directory will be a symlink to the release
|
54
54
|
|
55
|
+
Scenario: Cleanup
|
56
|
+
Given config stage file has line "set :keep_releases, 3"
|
57
|
+
And 5 valid existing releases
|
58
|
+
And an invalid release named "new"
|
59
|
+
When I run cap "deploy:cleanup"
|
60
|
+
Then 3 valid releases are kept
|
61
|
+
And the invalid "new" release is ignored
|
62
|
+
|
63
|
+
Scenario: Rolling Back
|
64
|
+
Given I make 2 deployments
|
65
|
+
When I run cap "deploy:rollback"
|
66
|
+
Then the current symlink points to the previous release
|
67
|
+
|
68
|
+
Scenario: Rolling Back to a specific release
|
69
|
+
Given I make 3 deployments
|
70
|
+
When I rollback to a specific release
|
71
|
+
Then the current symlink points to that specific release
|
72
|
+
|
@@ -6,7 +6,9 @@ end
|
|
6
6
|
|
7
7
|
Then(/^git wrapper permissions are 0700$/) do
|
8
8
|
permissions_test = %Q([ $(stat -c "%a" #{TestApp.git_wrapper_path.shellescape}) == "700" ])
|
9
|
-
|
9
|
+
_stdout, _stderr, status = vagrant_cli_command("ssh -c #{permissions_test.shellescape}")
|
10
|
+
|
11
|
+
expect(status).to be_success
|
10
12
|
end
|
11
13
|
|
12
14
|
Then(/^the shared path is created$/) do
|
@@ -17,6 +19,18 @@ Then(/^the releases path is created$/) do
|
|
17
19
|
run_vagrant_command(test_dir_exists(TestApp.releases_path))
|
18
20
|
end
|
19
21
|
|
22
|
+
Then(/^(\d+) valid releases are kept/) do |num|
|
23
|
+
test = %Q([ $(ls -g #{TestApp.releases_path} | grep -E '[0-9]{14}' | wc -l) == "#{num}" ])
|
24
|
+
_, _, status = vagrant_cli_command("ssh -c #{test.shellescape}")
|
25
|
+
expect(status).to be_success
|
26
|
+
end
|
27
|
+
|
28
|
+
Then(/^the invalid (.+) release is ignored$/) do |filename|
|
29
|
+
test = "ls -g #{TestApp.releases_path} | grep #{filename}"
|
30
|
+
_, _, status = vagrant_cli_command("ssh -c #{test.shellescape}")
|
31
|
+
expect(status).to be_success
|
32
|
+
end
|
33
|
+
|
20
34
|
Then(/^directories in :linked_dirs are created in shared$/) do
|
21
35
|
TestApp.linked_dirs.each do |dir|
|
22
36
|
run_vagrant_command(test_dir_exists(TestApp.shared_path.join(dir)))
|
@@ -124,3 +138,15 @@ end
|
|
124
138
|
Then(/doesn't contain "([^"]*)" in the output/) do |expected|
|
125
139
|
expect(@output).not_to include(expected)
|
126
140
|
end
|
141
|
+
|
142
|
+
Then(/the current symlink points to the previous release/) do
|
143
|
+
previous_release_path = @release_paths[-2]
|
144
|
+
|
145
|
+
run_vagrant_command(symlinked?(TestApp.current_path, previous_release_path))
|
146
|
+
end
|
147
|
+
|
148
|
+
Then(/^the current symlink points to that specific release$/) do
|
149
|
+
specific_release_path = TestApp.releases_path.join(@rollback_release)
|
150
|
+
|
151
|
+
run_vagrant_command(symlinked?(TestApp.current_path, specific_release_path))
|
152
|
+
end
|
@@ -13,3 +13,9 @@ end
|
|
13
13
|
When(/^I run "(.*?)"$/) do |command|
|
14
14
|
@success, @output = TestApp.run(command)
|
15
15
|
end
|
16
|
+
|
17
|
+
When(/^I rollback to a specific release$/) do
|
18
|
+
@rollback_release = @release_paths.first.split("/").last
|
19
|
+
|
20
|
+
step %Q{I run cap "deploy:rollback ROLLBACK_RELEASE=#{@rollback_release}"}
|
21
|
+
end
|
@@ -21,10 +21,16 @@ end
|
|
21
21
|
|
22
22
|
Given(/^file "(.*?)" exists in shared path$/) do |file|
|
23
23
|
file_shared_path = TestApp.shared_path.join(file)
|
24
|
-
run_vagrant_command("mkdir -p #{
|
24
|
+
run_vagrant_command("mkdir -p #{file_shared_path.dirname}")
|
25
25
|
run_vagrant_command("touch #{file_shared_path}")
|
26
26
|
end
|
27
27
|
|
28
|
+
Given(/^all linked files exists in shared path$/) do
|
29
|
+
TestApp.linked_files.each do |linked_file|
|
30
|
+
step %Q{file "#{linked_file}" exists in shared path}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
28
34
|
Given(/^file "(.*?)" does not exist in shared path$/) do |file|
|
29
35
|
file_shared_path = TestApp.shared_path.join(file)
|
30
36
|
run_vagrant_command("mkdir -p #{TestApp.shared_path}")
|
@@ -60,3 +66,27 @@ end
|
|
60
66
|
Given(/^a stage file named (.+)$/) do |filename|
|
61
67
|
TestApp.write_local_stage_file(filename)
|
62
68
|
end
|
69
|
+
|
70
|
+
Given(/^I make (\d+) deployments$/) do |count|
|
71
|
+
step "all linked files exists in shared path"
|
72
|
+
|
73
|
+
@release_paths = (1..count.to_i).map do
|
74
|
+
TestApp.cap("deploy")
|
75
|
+
stdout, _stderr = run_vagrant_command("readlink #{TestApp.current_path}")
|
76
|
+
|
77
|
+
stdout.strip
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
Given(/^(\d+) valid existing releases$/) do |num|
|
82
|
+
a_day = 86_400 # in seconds
|
83
|
+
offset = -(a_day * num.to_i)
|
84
|
+
num.to_i.times do
|
85
|
+
run_vagrant_command("mkdir -p #{TestApp.release_path(TestApp.timestamp(offset))}")
|
86
|
+
offset += a_day
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Given(/^an invalid release named "(.+)"$/) do |filename|
|
91
|
+
run_vagrant_command("mkdir -p #{TestApp.release_path(filename)}")
|
92
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "open3"
|
2
2
|
|
3
3
|
module VagrantHelpers
|
4
4
|
extend self
|
@@ -16,17 +16,18 @@ module VagrantHelpers
|
|
16
16
|
|
17
17
|
def vagrant_cli_command(command)
|
18
18
|
puts "[vagrant] #{command}"
|
19
|
-
Dir.chdir(VAGRANT_ROOT) do
|
20
|
-
|
21
|
-
puts "[vagrant] #{line}"
|
22
|
-
end
|
19
|
+
stdout, stderr, status = Dir.chdir(VAGRANT_ROOT) do
|
20
|
+
Open3.capture3("#{VAGRANT_BIN} #{command}")
|
23
21
|
end
|
24
|
-
|
22
|
+
|
23
|
+
(stdout + stderr).each_line { |line| puts "[vagrant] #{line}" }
|
24
|
+
|
25
|
+
[stdout, stderr, status]
|
25
26
|
end
|
26
27
|
|
27
28
|
def run_vagrant_command(command)
|
28
|
-
status = vagrant_cli_command("ssh -c #{command.inspect}")
|
29
|
-
return
|
29
|
+
stdout, stderr, status = vagrant_cli_command("ssh -c #{command.inspect}")
|
30
|
+
return [stdout, stderr] if status.success?
|
30
31
|
raise VagrantSSHCommandError, status
|
31
32
|
end
|
32
33
|
end
|
data/lib/capistrano/dsl.rb
CHANGED
@@ -19,13 +19,19 @@ module Capistrano
|
|
19
19
|
colors = SSHKit::Color.new($stderr)
|
20
20
|
$stderr.puts colors.colorize("Skipping task `#{task_name}'.", :yellow)
|
21
21
|
$stderr.puts "Capistrano tasks may only be invoked once. Since task `#{task}' was previously invoked, invoke(\"#{task_name}\") at #{file}:#{line} will be skipped."
|
22
|
-
$stderr.puts "If you really meant to run this task again,
|
22
|
+
$stderr.puts "If you really meant to run this task again, use invoke!(\"#{task_name}\")"
|
23
23
|
$stderr.puts colors.colorize("THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF CAPISTRANO. Please join the conversation here if this affects you.", :red)
|
24
24
|
$stderr.puts colors.colorize("https://github.com/capistrano/capistrano/issues/1686", :red)
|
25
25
|
end
|
26
26
|
task.invoke(*args)
|
27
27
|
end
|
28
28
|
|
29
|
+
def invoke!(task_name, *args)
|
30
|
+
task = Rake::Task[task_name]
|
31
|
+
task.reenable
|
32
|
+
task.invoke(*args)
|
33
|
+
end
|
34
|
+
|
29
35
|
def t(key, options={})
|
30
36
|
I18n.t(key, options.merge(scope: :capistrano))
|
31
37
|
end
|
data/lib/capistrano/i18n.rb
CHANGED
@@ -13,7 +13,7 @@ en = {
|
|
13
13
|
question: "Please enter %{key}: ",
|
14
14
|
question_default: "Please enter %{key} (%{default_value}): ",
|
15
15
|
keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
|
16
|
-
skip_cleanup: "Skipping cleanup of
|
16
|
+
skip_cleanup: "Skipping cleanup of invalid releases on %{host}; unexpected foldername found (should be timestamp)",
|
17
17
|
no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
|
18
18
|
linked_file_does_not_exist: "linked file %{file} does not exist on %{host}",
|
19
19
|
cannot_rollback: "There are no older releases to rollback to",
|
@@ -149,11 +149,13 @@ namespace :deploy do
|
|
149
149
|
task :cleanup do
|
150
150
|
on release_roles :all do |host|
|
151
151
|
releases = capture(:ls, "-x", releases_path).split
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
152
|
+
valid, invalid = releases.partition { |e| /^\d{14}$/ =~ e }
|
153
|
+
|
154
|
+
warn t(:skip_cleanup, host: host.to_s) if invalid.any?
|
155
|
+
|
156
|
+
if valid.count >= fetch(:keep_releases)
|
157
|
+
info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: valid.count)
|
158
|
+
directories = (valid - valid.last(fetch(:keep_releases)))
|
157
159
|
if directories.any?
|
158
160
|
directories_str = directories.map do |release|
|
159
161
|
releases_path.join(release)
|
data/lib/capistrano/version.rb
CHANGED
@@ -71,13 +71,54 @@ module Capistrano
|
|
71
71
|
end
|
72
72
|
|
73
73
|
describe "#invoke" do
|
74
|
-
|
75
|
-
|
74
|
+
context "reinvoking" do
|
75
|
+
it "will not reenable invoking task" do
|
76
|
+
counter = 0
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
Rake::Task.define_task("A") do
|
79
|
+
counter += 1
|
80
|
+
end
|
81
|
+
|
82
|
+
expect do
|
83
|
+
dsl.invoke("A")
|
84
|
+
dsl.invoke("A")
|
85
|
+
end.to change { counter }.by(1)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "will print a message on stderr" do
|
89
|
+
Rake::Task.define_task("B")
|
90
|
+
|
91
|
+
expect do
|
92
|
+
dsl.invoke("B")
|
93
|
+
dsl.invoke("B")
|
94
|
+
end.to output(/If you really meant to run this task again, use invoke!/).to_stderr
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#invoke!" do
|
100
|
+
context "reinvoking" do
|
101
|
+
it "will reenable invoking task" do
|
102
|
+
counter = 0
|
103
|
+
|
104
|
+
Rake::Task.define_task("C") do
|
105
|
+
counter += 1
|
106
|
+
end
|
107
|
+
|
108
|
+
expect do
|
109
|
+
dsl.invoke!("C")
|
110
|
+
dsl.invoke!("C")
|
111
|
+
end.to change { counter }.by(2)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "will not print a message on stderr" do
|
115
|
+
Rake::Task.define_task("D")
|
116
|
+
|
117
|
+
expect do
|
118
|
+
dsl.invoke!("D")
|
119
|
+
dsl.invoke!("D")
|
120
|
+
end.to_not output(/If you really meant to run this task again, use invoke!/).to_stderr
|
121
|
+
end
|
81
122
|
end
|
82
123
|
end
|
83
124
|
end
|
data/spec/support/test_app.rb
CHANGED
@@ -132,12 +132,12 @@ module TestApp
|
|
132
132
|
deploy_to.join("releases")
|
133
133
|
end
|
134
134
|
|
135
|
-
def release_path
|
136
|
-
releases_path.join(
|
135
|
+
def release_path(t=timestamp)
|
136
|
+
releases_path.join(t)
|
137
137
|
end
|
138
138
|
|
139
|
-
def timestamp
|
140
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
139
|
+
def timestamp(offset=0)
|
140
|
+
(Time.now.utc + offset).strftime("%Y%m%d%H%M%S")
|
141
141
|
end
|
142
142
|
|
143
143
|
def repo_path
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Clements
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-07-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: airbrussh
|
@@ -285,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
285
285
|
version: '0'
|
286
286
|
requirements: []
|
287
287
|
rubyforge_project:
|
288
|
-
rubygems_version: 2.6.
|
288
|
+
rubygems_version: 2.6.12
|
289
289
|
signing_key:
|
290
290
|
specification_version: 4
|
291
291
|
summary: Capistrano - Welcome to easy deployment with Ruby over SSH
|