capistrano 3.11.0 → 3.19.1

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/Dockerfile +7 -0
  3. data/.docker/ssh_key_rsa +49 -0
  4. data/.docker/ssh_key_rsa.pub +1 -0
  5. data/.docker/ubuntu_setup.sh +23 -0
  6. data/.github/pull_request_template.md +0 -4
  7. data/.github/release-drafter.yml +25 -0
  8. data/.github/workflows/ci.yml +80 -0
  9. data/.github/workflows/release-drafter.yml +18 -0
  10. data/.rubocop.yml +4 -3
  11. data/CHANGELOG.md +1 -651
  12. data/DEVELOPMENT.md +5 -20
  13. data/Gemfile +40 -3
  14. data/LICENSE.txt +1 -1
  15. data/README.md +3 -3
  16. data/RELEASING.md +3 -3
  17. data/Rakefile +13 -5
  18. data/capistrano.gemspec +8 -7
  19. data/docker-compose.yml +8 -0
  20. data/features/deploy.feature +11 -1
  21. data/features/sshconnect.feature +1 -1
  22. data/features/step_definitions/assertions.rb +34 -24
  23. data/features/step_definitions/setup.rb +15 -16
  24. data/features/support/docker_gateway.rb +53 -0
  25. data/features/support/env.rb +0 -10
  26. data/features/support/remote_command_helpers.rb +3 -3
  27. data/features/support/remote_ssh_helpers.rb +33 -0
  28. data/lib/capistrano/configuration/question.rb +16 -4
  29. data/lib/capistrano/configuration/validated_variables.rb +1 -1
  30. data/lib/capistrano/doctor/variables_doctor.rb +2 -0
  31. data/lib/capistrano/dsl.rb +1 -1
  32. data/lib/capistrano/i18n.rb +2 -0
  33. data/lib/capistrano/scm/git.rb +15 -4
  34. data/lib/capistrano/scm/tasks/git.rake +19 -7
  35. data/lib/capistrano/tasks/deploy.rake +26 -3
  36. data/lib/capistrano/templates/deploy.rb.erb +2 -2
  37. data/lib/capistrano/templates/stage.rb.erb +1 -1
  38. data/lib/capistrano/version.rb +1 -1
  39. data/spec/integration/dsl_spec.rb +16 -14
  40. data/spec/lib/capistrano/application_spec.rb +16 -40
  41. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +1 -1
  42. data/spec/lib/capistrano/configuration/question_spec.rb +31 -13
  43. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +4 -2
  44. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +1 -1
  45. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +1 -1
  46. data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +1 -1
  47. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +1 -1
  48. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +6 -6
  49. data/spec/lib/capistrano/dsl_spec.rb +5 -5
  50. data/spec/lib/capistrano/plugin_spec.rb +2 -2
  51. data/spec/lib/capistrano/scm/git_spec.rb +37 -5
  52. data/spec/spec_helper.rb +13 -0
  53. data/spec/support/test_app.rb +23 -14
  54. metadata +25 -73
  55. data/.travis.yml +0 -27
  56. data/Dangerfile +0 -1
  57. data/features/support/vagrant_helpers.rb +0 -35
  58. data/spec/support/.gitignore +0 -1
  59. data/spec/support/Vagrantfile +0 -23
@@ -60,7 +60,7 @@ module Capistrano
60
60
  end
61
61
  end
62
62
 
63
- it "prints helpful message to stderr" do
63
+ it "prints helpful message to stderr", capture_io: true do
64
64
  expect do
65
65
  expect do
66
66
  task.invoke
@@ -72,7 +72,7 @@ module Capistrano
72
72
 
73
73
  describe "#invoke" do
74
74
  context "reinvoking" do
75
- it "will not reenable invoking task" do
75
+ it "will not re-enable invoking task", capture_io: true do
76
76
  counter = 0
77
77
 
78
78
  Rake::Task.define_task("A") do
@@ -85,7 +85,7 @@ module Capistrano
85
85
  end.to change { counter }.by(1)
86
86
  end
87
87
 
88
- it "will print a message on stderr" do
88
+ it "will print a message on stderr", capture_io: true do
89
89
  Rake::Task.define_task("B")
90
90
 
91
91
  expect do
@@ -98,7 +98,7 @@ module Capistrano
98
98
 
99
99
  describe "#invoke!" do
100
100
  context "reinvoking" do
101
- it "will reenable invoking task" do
101
+ it "will re-enable invoking task", capture_io: true do
102
102
  counter = 0
103
103
 
104
104
  Rake::Task.define_task("C") do
@@ -111,7 +111,7 @@ module Capistrano
111
111
  end.to change { counter }.by(2)
112
112
  end
113
113
 
114
- it "will not print a message on stderr" do
114
+ it "will not print a message on stderr", capture_io: true do
115
115
  Rake::Task.define_task("D")
116
116
 
117
117
  expect do
@@ -62,14 +62,14 @@ module Capistrano
62
62
  dummy.expects(:set_defaults).never
63
63
  end
64
64
 
65
- it "calls set_defaults during load:defaults" do
65
+ it "calls set_defaults during load:defaults", capture_io: true do
66
66
  dummy = DummyPlugin.new
67
67
  dummy.expects(:set_defaults).once
68
68
  install_plugin(dummy)
69
69
  Rake::Task["load:defaults"].invoke
70
70
  end
71
71
 
72
- it "is able to load tasks from a .rake file" do
72
+ it "is able to load tasks from a .rake file", capture_io: true do
73
73
  install_plugin(ExternalTasksPlugin)
74
74
  Rake::Task["plugin_test"].invoke
75
75
  expect(fetch(:plugin_result)).to eq("hello")
@@ -19,6 +19,7 @@ module Capistrano
19
19
  Rake::Task.define_task("deploy:new_release_path")
20
20
  Rake::Task.define_task("deploy:check")
21
21
  Rake::Task.define_task("deploy:set_current_revision")
22
+ Rake::Task.define_task("deploy:set_current_revision_time")
22
23
  end
23
24
 
24
25
  # Clean up any tasks or variables that the plugin defined.
@@ -28,13 +29,24 @@ module Capistrano
28
29
  end
29
30
 
30
31
  describe "#set_defaults" do
31
- it "makes git_wrapper_path using application, stage, and local_user" do
32
+ it "makes git_wrapper_path using a random hex value" do
32
33
  env.set(:tmp_dir, "/tmp")
33
- env.set(:application, "my_app")
34
- env.set(:stage, "staging")
35
- env.set(:local_user, "(Git Web User) via ShipIt")
36
34
  subject.set_defaults
37
- expect(env.fetch(:git_wrapper_path)).to eq("/tmp/git-ssh-my_app-staging-(Git Web User) via ShipIt.sh")
35
+ expect(env.fetch(:git_wrapper_path)).to match(%r{/tmp/git-ssh-\h{20}\.sh})
36
+ end
37
+
38
+ it "makes git_max_concurrent_connections" do
39
+ subject.set_defaults
40
+ expect(env.fetch(:git_max_concurrent_connections)).to eq(10)
41
+ env.set(:git_max_concurrent_connections, 7)
42
+ expect(env.fetch(:git_max_concurrent_connections)).to eq(7)
43
+ end
44
+
45
+ it "makes git_wait_interval" do
46
+ subject.set_defaults
47
+ expect(env.fetch(:git_wait_interval)).to eq(0)
48
+ env.set(:git_wait_interval, 5)
49
+ expect(env.fetch(:git_wait_interval)).to eq(5)
38
50
  end
39
51
  end
40
52
 
@@ -158,5 +170,25 @@ module Capistrano
158
170
  expect(revision).to eq("81cec13b777ff46348693d327fc8e7832f79bf43")
159
171
  end
160
172
  end
173
+
174
+ describe "#fetch_revision_time" do
175
+ it "should capture git log without a pager" do
176
+ env.set(:branch, "branch")
177
+ backend.expects(:capture).with(:git, "--no-pager log -1 --pretty=format:\"%ct\" branch").returns("1715828406")
178
+ revision_time = subject.fetch_revision_time
179
+ expect(revision_time).to eq("1715828406")
180
+ end
181
+ end
182
+
183
+ describe "#verify_commit" do
184
+ it "should run git verify-commit" do
185
+ env.set(:branch, "branch")
186
+
187
+ backend.expects(:capture).with(:git, "rev-list --max-count=1 branch").returns("81cec13b777ff46348693d327fc8e7832f79bf43")
188
+ backend.expects(:execute).with(:git, :"verify-commit", "81cec13b777ff46348693d327fc8e7832f79bf43")
189
+
190
+ subject.verify_commit
191
+ end
192
+ end
161
193
  end
162
194
  end
data/spec/spec_helper.rb CHANGED
@@ -13,4 +13,17 @@ RSpec.configure do |config|
13
13
  config.raise_errors_for_deprecations!
14
14
  config.mock_framework = :mocha
15
15
  config.order = "random"
16
+
17
+ config.around(:example, capture_io: true) do |example|
18
+ begin
19
+ Rake.application.options.trace_output = StringIO.new
20
+ $stdout = StringIO.new
21
+ $stderr = StringIO.new
22
+ example.run
23
+ ensure
24
+ Rake.application.options.trace_output = STDERR
25
+ $stdout = STDOUT
26
+ $stderr = STDERR
27
+ end
28
+ end
16
29
  end
@@ -1,6 +1,7 @@
1
1
  require "English"
2
2
  require "fileutils"
3
3
  require "pathname"
4
+ require "open3"
4
5
 
5
6
  module TestApp
6
7
  extend self
@@ -12,10 +13,10 @@ module TestApp
12
13
  def default_config
13
14
  <<-CONFIG
14
15
  set :deploy_to, '#{deploy_to}'
15
- set :repo_url, 'git://github.com/capistrano/capistrano.git'
16
+ set :repo_url, 'https://github.com/capistrano/capistrano.git'
16
17
  set :branch, 'master'
17
- set :ssh_options, { keys: "\#{ENV['HOME']}/.vagrant.d/insecure_private_key", auth_methods: ['publickey'] }
18
- server 'vagrant@localhost:2220', roles: %w{web app}
18
+ set :ssh_options, { keys: '#{File.expand_path('../../.docker/ssh_key_rsa', __dir__)}', auth_methods: ['publickey'] }
19
+ server 'deployer@localhost:2022', roles: %w{web app}
19
20
  set :linked_files, #{linked_files}
20
21
  set :linked_dirs, #{linked_dirs}
21
22
  set :format_options, log_file: nil
@@ -39,9 +40,13 @@ module TestApp
39
40
  FileUtils.rm_rf(test_app_path)
40
41
  FileUtils.mkdir(test_app_path)
41
42
 
42
- File.open(gemfile, "w+") do |file|
43
- file.write "gem 'capistrano', path: '#{path_to_cap}'"
44
- end
43
+ File.write(gemfile, <<-GEMFILE.gsub(/^\s+/, ""))
44
+ source "https://rubygems.org"
45
+
46
+ gem "capistrano", path: #{path_to_cap.to_s.inspect}
47
+ gem "ed25519", ">= 1.2", "< 2.0"
48
+ gem "bcrypt_pbkdf", ">= 1.0", "< 2.0"
49
+ GEMFILE
45
50
 
46
51
  Dir.chdir(test_app_path) do
47
52
  run "bundle"
@@ -95,13 +100,12 @@ module TestApp
95
100
  end
96
101
 
97
102
  def run(command, subdirectory=nil)
98
- output = nil
99
103
  command = "bundle exec #{command}" unless command =~ /^bundle\b/
100
104
  dir = subdirectory ? test_app_path.join(subdirectory) : test_app_path
101
- Dir.chdir(dir) do
102
- output = with_clean_bundler_env { `#{command}` }
105
+ output, status = Dir.chdir(dir) do
106
+ with_clean_bundler_env { Open3.capture2e(command) }
103
107
  end
104
- [$CHILD_STATUS.success?, output]
108
+ [status.success?, output]
105
109
  end
106
110
 
107
111
  def stage
@@ -117,7 +121,7 @@ module TestApp
117
121
  end
118
122
 
119
123
  def deploy_to
120
- Pathname.new("/home/vagrant/var/www/deploy")
124
+ Pathname.new("/home/deployer/var/www/deploy")
121
125
  end
122
126
 
123
127
  def shared_path
@@ -185,12 +189,17 @@ module TestApp
185
189
  FileUtils.mv(config_path, location)
186
190
  end
187
191
 
188
- def git_wrapper_path
189
- "/tmp/git-ssh-my_app_name-#{stage}-#{current_user}.sh"
192
+ def git_wrapper_path_glob
193
+ "/tmp/git-ssh-*.sh"
190
194
  end
191
195
 
192
196
  def with_clean_bundler_env(&block)
193
197
  return yield unless defined?(Bundler)
194
- Bundler.with_clean_env(&block)
198
+
199
+ if Bundler.respond_to?(:with_unbundled_env)
200
+ Bundler.with_unbundled_env(&block)
201
+ else
202
+ Bundler.with_clean_env(&block)
203
+ end
195
204
  end
196
205
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Clements
8
8
  - Lee Hambley
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-06-03 00:00:00.000000000 Z
12
+ date: 2024-07-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: airbrussh
@@ -67,62 +67,6 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: 1.9.0
70
- - !ruby/object:Gem::Dependency
71
- name: danger
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: '0'
77
- type: :development
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: mocha
86
- requirement: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :development
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: '0'
98
- - !ruby/object:Gem::Dependency
99
- name: rspec
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- type: :development
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: rubocop
114
- requirement: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - '='
117
- - !ruby/object:Gem::Version
118
- version: 0.48.1
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - '='
124
- - !ruby/object:Gem::Version
125
- version: 0.48.1
126
70
  description: Capistrano is a utility and framework for executing commands in parallel
127
71
  on multiple remote machines, via SSH.
128
72
  email:
@@ -134,15 +78,20 @@ executables:
134
78
  extensions: []
135
79
  extra_rdoc_files: []
136
80
  files:
81
+ - ".docker/Dockerfile"
82
+ - ".docker/ssh_key_rsa"
83
+ - ".docker/ssh_key_rsa.pub"
84
+ - ".docker/ubuntu_setup.sh"
137
85
  - ".github/issue_template.md"
138
86
  - ".github/pull_request_template.md"
87
+ - ".github/release-drafter.yml"
88
+ - ".github/workflows/ci.yml"
89
+ - ".github/workflows/release-drafter.yml"
139
90
  - ".gitignore"
140
91
  - ".rubocop.yml"
141
- - ".travis.yml"
142
92
  - CHANGELOG.md
143
93
  - CONTRIBUTING.md
144
94
  - DEVELOPMENT.md
145
- - Dangerfile
146
95
  - Gemfile
147
96
  - LICENSE.txt
148
97
  - README.md
@@ -152,6 +101,7 @@ files:
152
101
  - bin/cap
153
102
  - bin/capify
154
103
  - capistrano.gemspec
104
+ - docker-compose.yml
155
105
  - features/configuration.feature
156
106
  - features/deploy.feature
157
107
  - features/deploy_failure.feature
@@ -163,9 +113,10 @@ files:
163
113
  - features/step_definitions/cap_commands.rb
164
114
  - features/step_definitions/setup.rb
165
115
  - features/subdirectory.feature
116
+ - features/support/docker_gateway.rb
166
117
  - features/support/env.rb
167
118
  - features/support/remote_command_helpers.rb
168
- - features/support/vagrant_helpers.rb
119
+ - features/support/remote_ssh_helpers.rb
169
120
  - lib/Capfile
170
121
  - lib/capistrano.rb
171
122
  - lib/capistrano/all.rb
@@ -256,8 +207,6 @@ files:
256
207
  - spec/lib/capistrano/version_validator_spec.rb
257
208
  - spec/lib/capistrano_spec.rb
258
209
  - spec/spec_helper.rb
259
- - spec/support/.gitignore
260
- - spec/support/Vagrantfile
261
210
  - spec/support/matchers.rb
262
211
  - spec/support/tasks/database.rake
263
212
  - spec/support/tasks/fail.rake
@@ -265,11 +214,16 @@ files:
265
214
  - spec/support/tasks/plugin.rake
266
215
  - spec/support/tasks/root.rake
267
216
  - spec/support/test_app.rb
268
- homepage: http://capistranorb.com/
217
+ homepage: https://capistranorb.com/
269
218
  licenses:
270
219
  - MIT
271
- metadata: {}
272
- post_install_message:
220
+ metadata:
221
+ bug_tracker_uri: https://github.com/capistrano/capistrano/issues
222
+ changelog_uri: https://github.com/capistrano/capistrano/releases
223
+ source_code_uri: https://github.com/capistrano/capistrano
224
+ homepage_uri: https://capistranorb.com/
225
+ documentation_uri: https://capistranorb.com/
226
+ post_install_message:
273
227
  rdoc_options: []
274
228
  require_paths:
275
229
  - lib
@@ -284,9 +238,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
238
  - !ruby/object:Gem::Version
285
239
  version: '0'
286
240
  requirements: []
287
- rubyforge_project:
288
- rubygems_version: 2.7.7
289
- signing_key:
241
+ rubygems_version: 3.5.8
242
+ signing_key:
290
243
  specification_version: 4
291
244
  summary: Capistrano - Welcome to easy deployment with Ruby over SSH
292
245
  test_files:
@@ -301,9 +254,10 @@ test_files:
301
254
  - features/step_definitions/cap_commands.rb
302
255
  - features/step_definitions/setup.rb
303
256
  - features/subdirectory.feature
257
+ - features/support/docker_gateway.rb
304
258
  - features/support/env.rb
305
259
  - features/support/remote_command_helpers.rb
306
- - features/support/vagrant_helpers.rb
260
+ - features/support/remote_ssh_helpers.rb
307
261
  - spec/integration/dsl_spec.rb
308
262
  - spec/integration_spec_helper.rb
309
263
  - spec/lib/capistrano/application_spec.rb
@@ -336,8 +290,6 @@ test_files:
336
290
  - spec/lib/capistrano/version_validator_spec.rb
337
291
  - spec/lib/capistrano_spec.rb
338
292
  - spec/spec_helper.rb
339
- - spec/support/.gitignore
340
- - spec/support/Vagrantfile
341
293
  - spec/support/matchers.rb
342
294
  - spec/support/tasks/database.rake
343
295
  - spec/support/tasks/fail.rake
data/.travis.yml DELETED
@@ -1,27 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.4.1
4
- - 2.3.1
5
- - 2.2
6
- - 2.1
7
- - 2.0
8
- matrix:
9
- # Rubinius periodically fails in general, and it always segfaults for RuboCop
10
- # in particular. Until we figure out how to make it work consistently, allow
11
- # it to fail without breaking the build.
12
- allow_failures:
13
- - rvm: rbx-2
14
- include:
15
- - rvm: rbx-2
16
- script: bundle exec rake spec
17
- # Run Danger only once, on 2.3.1
18
- - rvm: 2.3.1
19
- before_script: bundle exec danger
20
-
21
- script: bundle exec rake spec rubocop
22
- install: bundle install --jobs=1
23
- cache: bundler
24
- branches:
25
- except:
26
- - legacy-v2
27
- sudo: false
data/Dangerfile DELETED
@@ -1 +0,0 @@
1
- danger.import_dangerfile(github: "capistrano/danger")
@@ -1,35 +0,0 @@
1
- require "open3"
2
-
3
- module VagrantHelpers
4
- extend self
5
-
6
- class VagrantSSHCommandError < RuntimeError; end
7
-
8
- at_exit do
9
- if ENV["KEEP_RUNNING"]
10
- puts "Vagrant vm will be left up because KEEP_RUNNING is set."
11
- puts "Rerun without KEEP_RUNNING set to cleanup the vm."
12
- else
13
- vagrant_cli_command("destroy -f")
14
- end
15
- end
16
-
17
- def vagrant_cli_command(command)
18
- puts "[vagrant] #{command}"
19
- stdout, stderr, status = Dir.chdir(VAGRANT_ROOT) do
20
- Open3.capture3("#{VAGRANT_BIN} #{command}")
21
- end
22
-
23
- (stdout + stderr).each_line { |line| puts "[vagrant] #{line}" }
24
-
25
- [stdout, stderr, status]
26
- end
27
-
28
- def run_vagrant_command(command)
29
- stdout, stderr, status = vagrant_cli_command("ssh -c #{command.inspect}")
30
- return [stdout, stderr] if status.success?
31
- raise VagrantSSHCommandError, status
32
- end
33
- end
34
-
35
- World(VagrantHelpers)
@@ -1 +0,0 @@
1
- .vagrant
@@ -1,23 +0,0 @@
1
- require "open-uri"
2
-
3
- Vagrant.configure("2") do |config|
4
- config.ssh.insert_key = false
5
-
6
- [:app].each_with_index do |role, i|
7
- config.vm.define(role, primary: true) do |primary|
8
- primary.vm.define role
9
- primary.vm.box = "hashicorp/precise64"
10
- primary.vm.network "forwarded_port", guest: 22, host: "222#{i}".to_i
11
- primary.vm.provision :shell, inline: "sudo apt-get -y install git-core"
12
-
13
- vagrantkey = open("https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub", "r", &:read)
14
-
15
- primary.vm.provision :shell,
16
- inline: <<-INLINE
17
- install -d -m 700 /root/.ssh
18
- echo -e "#{vagrantkey}" > /root/.ssh/authorized_keys
19
- chmod 0600 /root/.ssh/authorized_keys
20
- INLINE
21
- end
22
- end
23
- end