capistrano 3.11.0 → 3.19.1

Sign up to get free protection for your applications and to get access to all the features.
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