capistrano 3.18.1 → 3.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae53528854f57ad3fcd21f62cc4b8c39b9299acdc58fe133379874eec9ff8d7a
4
- data.tar.gz: 96bb90b2185d9512db08f3688f47d5d0a0ae56b8105a2f55ae0049c58256a2f9
3
+ metadata.gz: 394b09ce3f7d404792341024337f15b508055a5cff92fe9c3b3db0b30a195f86
4
+ data.tar.gz: 94609866fe948bfa1e7f9ded8fc76f0622fc7123733285a82ac300dc772ccbef
5
5
  SHA512:
6
- metadata.gz: b4d10e94df9a4e5b600a88337797dac5fb1c63458e2a8e567bfb25558fe0e1367ed579a001c7a42d17e135faba09a88aa18477fcfd8e63e27a471978e2d5c59b
7
- data.tar.gz: f6cb277aea4838f5da7c16c9005fd3d17b9fac43ec46aa2c07ea32f2930bb6aa0b1403ef13459a9b7a351bdd2486765cfba0e2d1ff0fd63882159a38f6ae7879
6
+ metadata.gz: 03eca17ed3fd4484babfee22ed9bbb6a844eb79b6141471295a6cd15fe7423b01322fc57ec9c4771e08eebfd02ac51cca9ea8fb4df230dd1104ed94c739bad6a
7
+ data.tar.gz: e622bfb56fc09785b8ca7c1cbb156c2c78348209acfe3b5ca7137d53f16a762c96e89a3a71d80f7ba9dfc29cd1c845cce69e5df8ea045da429252ce07a0dac64
@@ -0,0 +1,7 @@
1
+ FROM ubuntu:22.04
2
+ WORKDIR /provision
3
+ COPY ./ssh_key_rsa.pub /root/.ssh/authorized_keys
4
+ COPY ./ubuntu_setup.sh ./
5
+ RUN ./ubuntu_setup.sh
6
+ EXPOSE 22
7
+ CMD ["/usr/sbin/sshd", "-D"]
@@ -0,0 +1,49 @@
1
+ -----BEGIN OPENSSH PRIVATE KEY-----
2
+ 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
49
+ -----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6wVCoBOGYS5qfXZGiKjuh7RWExlzrQ1Gml8Z3DDCggSEibh1WXJU9+rNKTqHmVoGy36iarPfjsGWw3IbiWiMOXD7crg3BCyRbksAdrVV/MIq6BiKqnGaQvOV9AE5RbA6W4/prkEKL/tdnpVaWpMbtthEo6H/IO3Ih+iXomni4NkUBjDjJf6sr8B/vI4aIcp0I5/uXNI3zIWVhQ6yBZ4hORs8jPBMpe7jMoFb5z8t6AUUfmIc66JiLmLX2hqYEreIB7rzlPOsDsOByADubyA/r3zYaA5kZxLbHT+sgQitjb4TATdoCxX6+utxVQeRZK4YrCR3D/aWzhmOgl5OHxO7ArWgICXC18icrvDdUACxOWKRaSe0WXw0nX1L0ZteKuYsvFAf0t0nNPStnWkxzRA4snzJCiptuWcjx8p7WY0Ph267ERq9rNFgMDmSsHaYMOnJAXr8WF00zFcVgAW6b3MBJSmBEtcz45RvMDv4XiMvzZiP/1+we+JXI1f5Y8LhyVtkeME5J7u6LrNUI5bvBMyDodMkmOonRdpL4iwOUXwpETX7i8fsr7+8YFw+JtXQ0iePq4V2PmmPNXThljhkhConwVnGsfV4qfuGaGJgMKJfK/E6hF8W9ejEH9BvmX7l75fyAK0zMq+n6ohOr4M4wVcz9G+s+5vSZ5JNwYTyVrAthtw== test@example.com
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ export DEBIAN_FRONTEND=noninteractive
6
+
7
+ # Create `deployer` user
8
+ adduser --disabled-password deployer < /dev/null
9
+ mkdir -p /home/deployer/.ssh
10
+ cp /root/.ssh/authorized_keys /home/deployer/.ssh
11
+ chown -R deployer:deployer /home/deployer/.ssh
12
+ chmod 600 /home/deployer/.ssh/authorized_keys
13
+
14
+ # Install and configure sshd
15
+ apt -y update
16
+ apt-get -y install openssh-server git
17
+ {
18
+ echo "Port 22"
19
+ echo "PasswordAuthentication no"
20
+ echo "ChallengeResponseAuthentication no"
21
+ } >> /etc/ssh/sshd_config
22
+ mkdir /var/run/sshd
23
+ chmod 0755 /var/run/sshd
@@ -66,31 +66,11 @@ jobs:
66
66
  bundler-cache: true
67
67
  - name: rake rubocop
68
68
  run: bundle exec rake rubocop
69
- danger:
70
- runs-on: ubuntu-latest
71
- steps:
72
- - uses: actions/checkout@v4
73
- - name: Set up Ruby
74
- uses: ruby/setup-ruby@v1
75
- with:
76
- ruby-version: "ruby" # latest-stable
77
- bundler-cache: true
78
- - name: danger
79
- env:
80
- DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
81
- run: bundle exec danger
82
69
  features:
83
70
  needs: [spec, spec-legacy]
84
- runs-on: macos-12
71
+ runs-on: ubuntu-latest
85
72
  steps:
86
73
  - uses: actions/checkout@v4
87
- - name: Cache Vagrant boxes
88
- uses: actions/cache@v3
89
- with:
90
- path: ~/.vagrant.d/boxes
91
- key: ${{ runner.os }}-vagrant-${{ hashFiles('Vagrantfile') }}
92
- restore-keys: |
93
- ${{ runner.os }}-vagrant-
94
74
  - name: Set up Ruby
95
75
  uses: ruby/setup-ruby@v1
96
76
  with:
data/.rubocop.yml CHANGED
@@ -13,13 +13,13 @@ Metrics/BlockLength:
13
13
  - "lib/**/*.rake"
14
14
  Style/BarePercentLiterals:
15
15
  EnforcedStyle: percent_q
16
+ Style/BracesAroundHashParameters:
17
+ Exclude:
18
+ - spec/integration/dsl_spec.rb
16
19
  Style/ClassAndModuleChildren:
17
20
  Enabled: false
18
21
  Style/DoubleNegation:
19
22
  Enabled: false
20
- Style/FileName:
21
- Exclude:
22
- - "Dangerfile"
23
23
  Style/IndentHeredoc:
24
24
  Enabled: false
25
25
  Style/SpaceAroundEqualsInParameterDefault:
data/DEVELOPMENT.md CHANGED
@@ -20,22 +20,16 @@ Everyone can help improve Capistrano. There are ways to contribute even if you a
20
20
 
21
21
  ## Contributing documentation
22
22
 
23
- Improvements and additions to Capistrano's documentation are very much appreciated. The official documentation is stored in the `docs/` directory as Markdown files. These files are used to automatically generate the [capistranorb.com](http://capistranorb.com/) website, which is hosted by GitHub Pages. Feel free to make changes to this documentation as you see fit. Before opening a pull request, make sure your documentation renders correctly by previewing the website in your local environment. Refer to [docs/README.md][] for instructions.
23
+ Improvements and additions to Capistrano's documentation are very much appreciated. The official documentation is stored in the `docs/` directory as Markdown files. These files are used to automatically generate the [capistranorb.com](https://capistranorb.com/) website, which is hosted by GitHub Pages. Feel free to make changes to this documentation as you see fit. Before opening a pull request, make sure your documentation renders correctly by previewing the website in your local environment. Refer to [docs/README.md][] for instructions.
24
24
 
25
25
  ## Setting up your development environment
26
26
 
27
- Capistrano is a Ruby project, so we expect you to have a functioning Ruby environment. To hack on Capistrano you will further need some specialized tools to run its test suite.
28
-
29
- Make sure to install:
30
-
31
- * [Bundler](https://bundler.io/)
32
- * [Vagrant](https://www.vagrantup.com/)
33
- * [VirtualBox](https://www.virtualbox.org/wiki/Downloads) (or another [Vagrant-supported](https://docs.vagrantup.com/v2/getting-started/providers.html) VM host)
27
+ Capistrano is a Ruby project, so we expect you to have a functioning Ruby environment with the latest stable version of Ruby. To run Cucumber tests, you'll also need [Docker installed](https://docs.docker.com/get-docker/) and running.
34
28
 
35
29
 
36
30
  ### Running tests
37
31
 
38
- Capistrano has two test suites: an RSpec suite and a Cucumber suite. The RSpec suite handles quick feedback unit specs. The Cucumber suite is an integration suite that uses Vagrant to deploy to a real virtual server.
32
+ Capistrano has two test suites: an RSpec suite and a Cucumber suite. The RSpec suite handles quick feedback unit specs. The Cucumber suite is an integration suite that uses a Docker container as an SSH server and deployment target.
39
33
 
40
34
  ```
41
35
  # Ensure all dependencies are installed
@@ -44,11 +38,8 @@ $ bundle install
44
38
  # Run the RSpec suite
45
39
  $ bundle exec rake spec
46
40
 
47
- # Run the Cucumber suite
41
+ # Run the Cucumber suite (Docker must be running)
48
42
  $ bundle exec rake features
49
-
50
- # Run the Cucumber suite and leave the VM running (faster for subsequent runs)
51
- $ bundle exec rake features KEEP_RUNNING=1
52
43
  ```
53
44
 
54
45
  ## Coding guidelines
data/Gemfile CHANGED
@@ -38,10 +38,9 @@ if Gem::Requirement.new("< 2.2").satisfied_by?(Gem::Version.new(RUBY_VERSION))
38
38
  gem "rake", "< 13.0.0"
39
39
  end
40
40
 
41
- # We only run danger and rubocop on a new-ish ruby; no need to install them otherwise
41
+ # We only run rubocop and its dependencies on a new-ish ruby; no need to install them otherwise
42
42
  if Gem::Requirement.new("> 2.4").satisfied_by?(Gem::Version.new(RUBY_VERSION))
43
43
  gem "base64"
44
- gem "danger"
45
44
  gem "psych", "< 4" # Ensures rubocop works on Ruby 3.1
46
45
  gem "racc"
47
46
  gem "rubocop", "0.48.1"
@@ -0,0 +1,8 @@
1
+ name: capistrano
2
+
3
+ services:
4
+ ssh_server:
5
+ build:
6
+ context: .docker
7
+ ports:
8
+ - "2022:22"
@@ -40,6 +40,11 @@ Feature: Deploy
40
40
  Then the repo is cloned
41
41
  And the release is created
42
42
 
43
+ Scenario: REVISION and REVISION_TIME files are present
44
+ When I make 1 deployment
45
+ Then the REVISION file is created in the release
46
+ Then the REVISION_TIME file is created in the release
47
+
43
48
  Scenario: Symlink linked files
44
49
  When I run cap "deploy:symlink:linked_files deploy:symlink:release" as part of a release
45
50
  Then file symlinks are created in the new release
@@ -85,4 +90,3 @@ Feature: Deploy
85
90
  Given I make 3 deployments
86
91
  When I rollback to a specific release
87
92
  Then the current symlink points to that specific release
88
-
@@ -8,4 +8,4 @@ Feature: SSH Connection
8
8
  Scenario: Switching from default user to root and back again
9
9
  When I run cap "am_i_root"
10
10
  Then the task is successful
11
- And the output matches "I am uid=0\(root\)" followed by "I am uid=\d+\(vagrant\)"
11
+ And the output matches "I am uid=0\(root\)" followed by "I am uid=\d+\(deployer\)"
@@ -6,67 +6,77 @@ end
6
6
 
7
7
  Then(/^git wrapper permissions are 0700$/) do
8
8
  permissions_test = %Q([ $(stat -c "%a" #{TestApp.git_wrapper_path_glob}) == "700" ])
9
- _stdout, _stderr, status = vagrant_cli_command("ssh -c #{permissions_test.shellescape}")
10
-
11
- expect(status).to be_success
9
+ expect { run_remote_ssh_command(permissions_test) }.not_to raise_error
12
10
  end
13
11
 
14
12
  Then(/^the shared path is created$/) do
15
- run_vagrant_command(test_dir_exists(TestApp.shared_path))
13
+ run_remote_ssh_command(test_dir_exists(TestApp.shared_path))
16
14
  end
17
15
 
18
16
  Then(/^the releases path is created$/) do
19
- run_vagrant_command(test_dir_exists(TestApp.releases_path))
17
+ run_remote_ssh_command(test_dir_exists(TestApp.releases_path))
20
18
  end
21
19
 
22
20
  Then(/^(\d+) valid releases are kept/) do |num|
23
21
  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
22
+ expect { run_remote_ssh_command(test) }.not_to raise_error
26
23
  end
27
24
 
28
25
  Then(/^the invalid (.+) release is ignored$/) do |filename|
29
26
  test = "ls -g #{TestApp.releases_path} | grep #{filename}"
30
- _, _, status = vagrant_cli_command("ssh -c #{test.shellescape}")
31
- expect(status).to be_success
27
+ expect { run_remote_ssh_command(test) }.not_to raise_error
32
28
  end
33
29
 
34
30
  Then(/^directories in :linked_dirs are created in shared$/) do
35
31
  TestApp.linked_dirs.each do |dir|
36
- run_vagrant_command(test_dir_exists(TestApp.shared_path.join(dir)))
32
+ run_remote_ssh_command(test_dir_exists(TestApp.shared_path.join(dir)))
37
33
  end
38
34
  end
39
35
 
40
36
  Then(/^directories referenced in :linked_files are created in shared$/) do
41
37
  dirs = TestApp.linked_files.map { |path| TestApp.shared_path.join(path).dirname }
42
38
  dirs.each do |dir|
43
- run_vagrant_command(test_dir_exists(dir))
39
+ run_remote_ssh_command(test_dir_exists(dir))
44
40
  end
45
41
  end
46
42
 
47
43
  Then(/^the repo is cloned$/) do
48
- run_vagrant_command(test_dir_exists(TestApp.repo_path))
44
+ run_remote_ssh_command(test_dir_exists(TestApp.repo_path))
49
45
  end
50
46
 
51
47
  Then(/^the release is created$/) do
52
- run_vagrant_command("ls -g #{TestApp.releases_path}")
48
+ stdout, _stderr = run_remote_ssh_command("ls #{TestApp.releases_path}")
49
+
50
+ expect(stdout.strip).to match(/\A#{Time.now.utc.strftime("%Y%m%d")}\d{6}\Z/)
51
+ end
52
+
53
+ Then(/^the REVISION file is created in the release$/) do
54
+ stdout, _stderr = run_remote_ssh_command("cat #{@release_paths[0]}/REVISION")
55
+
56
+ expect(stdout.strip).to match(/\h{40}/)
57
+ end
58
+
59
+ Then(/^the REVISION_TIME file is created in the release$/) do
60
+ stdout, _stderr = run_remote_ssh_command("cat #{@release_paths[0]}/REVISION_TIME")
61
+
62
+ expect(stdout.strip).to match(/\d{10}/)
53
63
  end
54
64
 
55
65
  Then(/^file symlinks are created in the new release$/) do
56
66
  TestApp.linked_files.each do |file|
57
- run_vagrant_command(test_symlink_exists(TestApp.current_path.join(file)))
67
+ run_remote_ssh_command(test_symlink_exists(TestApp.current_path.join(file)))
58
68
  end
59
69
  end
60
70
 
61
71
  Then(/^directory symlinks are created in the new release$/) do
62
72
  pending
63
73
  TestApp.linked_dirs.each do |dir|
64
- run_vagrant_command(test_symlink_exists(TestApp.release_path.join(dir)))
74
+ run_remote_ssh_command(test_symlink_exists(TestApp.release_path.join(dir)))
65
75
  end
66
76
  end
67
77
 
68
78
  Then(/^the current directory will be a symlink to the release$/) do
69
- run_vagrant_command(exists?("e", TestApp.current_path))
79
+ run_remote_ssh_command(exists?("e", TestApp.current_path))
70
80
  end
71
81
 
72
82
  Then(/^the deploy\.rb file is created$/) do
@@ -95,7 +105,7 @@ end
95
105
 
96
106
  Then(/^it creates the file with the remote_task prerequisite$/) do
97
107
  TestApp.linked_files.each do |file|
98
- run_vagrant_command(test_file_exists(TestApp.shared_path.join(file)))
108
+ run_remote_ssh_command(test_file_exists(TestApp.shared_path.join(file)))
99
109
  end
100
110
  end
101
111
 
@@ -113,18 +123,18 @@ end
113
123
 
114
124
  Then(/^the failure task will run$/) do
115
125
  failed = TestApp.shared_path.join("failed")
116
- run_vagrant_command(test_file_exists(failed))
126
+ run_remote_ssh_command(test_file_exists(failed))
117
127
  end
118
128
 
119
129
  Then(/^the failure task will not run$/) do
120
130
  failed = TestApp.shared_path.join("failed")
121
- expect { run_vagrant_command(test_file_exists(failed)) }
122
- .to raise_error(VagrantHelpers::VagrantSSHCommandError)
131
+ expect { run_remote_ssh_command(test_file_exists(failed)) }
132
+ .to raise_error(RemoteSSHHelpers::RemoteSSHCommandError)
123
133
  end
124
134
 
125
135
  When(/^an error is raised$/) do
126
136
  error = TestApp.shared_path.join("fail")
127
- run_vagrant_command(test_file_exists(error))
137
+ run_remote_ssh_command(test_file_exists(error))
128
138
  end
129
139
 
130
140
  Then(/contains "([^"]*)" in the output/) do |expected|
@@ -142,11 +152,11 @@ end
142
152
  Then(/the current symlink points to the previous release/) do
143
153
  previous_release_path = @release_paths[-2]
144
154
 
145
- run_vagrant_command(symlinked?(TestApp.current_path, previous_release_path))
155
+ run_remote_ssh_command(symlinked?(TestApp.current_path, previous_release_path))
146
156
  end
147
157
 
148
158
  Then(/^the current symlink points to that specific release$/) do
149
159
  specific_release_path = TestApp.releases_path.join(@rollback_release)
150
160
 
151
- run_vagrant_command(symlinked?(TestApp.current_path, specific_release_path))
161
+ run_remote_ssh_command(symlinked?(TestApp.current_path, specific_release_path))
152
162
  end
@@ -7,11 +7,8 @@ Given(/^a test app without any configuration$/) do
7
7
  end
8
8
 
9
9
  Given(/^servers with the roles app and web$/) do
10
- begin
11
- vagrant_cli_command("up")
12
- rescue
13
- nil
14
- end
10
+ start_ssh_server
11
+ wait_for_ssh_server
15
12
  end
16
13
 
17
14
  Given(/^a linked file "(.*?)"$/) do |file|
@@ -21,8 +18,8 @@ end
21
18
 
22
19
  Given(/^file "(.*?)" exists in shared path$/) do |file|
23
20
  file_shared_path = TestApp.shared_path.join(file)
24
- run_vagrant_command("mkdir -p #{file_shared_path.dirname}")
25
- run_vagrant_command("touch #{file_shared_path}")
21
+ run_remote_ssh_command("mkdir -p #{file_shared_path.dirname}")
22
+ run_remote_ssh_command("touch #{file_shared_path}")
26
23
  end
27
24
 
28
25
  Given(/^all linked files exists in shared path$/) do
@@ -33,8 +30,8 @@ end
33
30
 
34
31
  Given(/^file "(.*?)" does not exist in shared path$/) do |file|
35
32
  file_shared_path = TestApp.shared_path.join(file)
36
- run_vagrant_command("mkdir -p #{TestApp.shared_path}")
37
- run_vagrant_command("touch #{file_shared_path} && rm #{file_shared_path}")
33
+ run_remote_ssh_command("mkdir -p #{TestApp.shared_path}")
34
+ run_remote_ssh_command("touch #{file_shared_path} && rm #{file_shared_path}")
38
35
  end
39
36
 
40
37
  Given(/^a custom task to generate a file$/) do
@@ -67,12 +64,12 @@ Given(/^a stage file named (.+)$/) do |filename|
67
64
  TestApp.write_local_stage_file(filename)
68
65
  end
69
66
 
70
- Given(/^I make (\d+) deployments$/) do |count|
67
+ Given(/^I make (\d+) deployments?$/) do |count|
71
68
  step "all linked files exists in shared path"
72
69
 
73
70
  @release_paths = (1..count.to_i).map do
74
71
  TestApp.cap("deploy")
75
- stdout, _stderr = run_vagrant_command("readlink #{TestApp.current_path}")
72
+ stdout, _stderr = run_remote_ssh_command("readlink #{TestApp.current_path}")
76
73
 
77
74
  stdout.strip
78
75
  end
@@ -85,10 +82,10 @@ Given(/^(\d+) valid existing releases$/) do |num|
85
82
  offset = -(a_day * i)
86
83
  TestApp.release_path(TestApp.timestamp(offset))
87
84
  end
88
- run_vagrant_command("mkdir -p #{dirs.join(' ')}")
85
+ run_remote_ssh_command("mkdir -p #{dirs.join(' ')}")
89
86
  end
90
87
  end
91
88
 
92
89
  Given(/^an invalid release named "(.+)"$/) do |filename|
93
- run_vagrant_command("mkdir -p #{TestApp.release_path(filename)}")
90
+ run_remote_ssh_command("mkdir -p #{TestApp.release_path(filename)}")
94
91
  end
@@ -0,0 +1,53 @@
1
+ # Ensure Docker container is completely stopped when Ruby exits.
2
+ at_exit do
3
+ DockerGateway.new.stop
4
+ end
5
+
6
+ # Manages the Docker-based SSH server that is declared in docker-compose.yml.
7
+ class DockerGateway
8
+ def initialize(log_proc=$stderr.method(:puts))
9
+ @log_proc = log_proc
10
+ end
11
+
12
+ def start
13
+ run_compose_command("up -d")
14
+ end
15
+
16
+ def stop
17
+ run_compose_command("down")
18
+ end
19
+
20
+ def run_shell_command(command)
21
+ run_compose_command("exec ssh_server /bin/bash -c #{command.shellescape}")
22
+ end
23
+
24
+ private
25
+
26
+ def run_compose_command(command)
27
+ log "[docker compose] #{command}"
28
+ stdout, stderr, status = Open3.popen3("docker compose #{command}") do |stdin, stdout, stderr, wait_threads|
29
+ stdin << ""
30
+ stdin.close
31
+ out = Thread.new { read_lines(stdout, &$stdout.method(:puts)) }
32
+ err = Thread.new { stderr.read }
33
+ [out.value, err.value.to_s, wait_threads.value]
34
+ end
35
+
36
+ (stdout + stderr).each_line { |line| log "[docker compose] #{line}" }
37
+
38
+ [stdout, stderr, status]
39
+ end
40
+
41
+ def read_lines(io)
42
+ buffer = + ""
43
+ while (line = io.gets)
44
+ buffer << line
45
+ yield line
46
+ end
47
+ buffer
48
+ end
49
+
50
+ def log(message)
51
+ @log_proc.call(message)
52
+ end
53
+ end
@@ -1,11 +1 @@
1
- PROJECT_ROOT = File.expand_path("../../../", __FILE__)
2
- VAGRANT_ROOT = File.join(PROJECT_ROOT, "spec/support")
3
- VAGRANT_BIN = ENV["VAGRANT_BIN"] || "vagrant"
4
-
5
- at_exit do
6
- if ENV["KEEP_RUNNING"]
7
- VagrantHelpers.run_vagrant_command("rm -rf /home/vagrant/var")
8
- end
9
- end
10
-
11
1
  require_relative "../../spec/support/test_app"
@@ -12,7 +12,7 @@ module RemoteCommandHelpers
12
12
  end
13
13
 
14
14
  def exists?(type, path)
15
- %Q{[ -#{type} "#{path}" ]}
15
+ %Q{[[ -#{type} "#{path}" ]]}
16
16
  end
17
17
 
18
18
  def symlinked?(symlink_path, target_path)
@@ -20,9 +20,9 @@ module RemoteCommandHelpers
20
20
  end
21
21
 
22
22
  def safely_remove_file(_path)
23
- run_vagrant_command("rm #{test_file}")
23
+ run_remote_ssh_command("rm #{test_file}")
24
24
  rescue
25
- VagrantHelpers::VagrantSSHCommandError
25
+ RemoteSSHHelpers::RemoteSSHCommandError
26
26
  end
27
27
  end
28
28
 
@@ -0,0 +1,33 @@
1
+ require "open3"
2
+ require "socket"
3
+ require_relative "docker_gateway"
4
+
5
+ module RemoteSSHHelpers
6
+ extend self
7
+
8
+ class RemoteSSHCommandError < RuntimeError; end
9
+
10
+ def start_ssh_server
11
+ docker_gateway.start
12
+ end
13
+
14
+ def wait_for_ssh_server(retries=3)
15
+ Socket.tcp("localhost", 2022, connect_timeout: 1).close
16
+ rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT
17
+ retries -= 1
18
+ sleep(2) && retry if retries.positive?
19
+ raise
20
+ end
21
+
22
+ def run_remote_ssh_command(command)
23
+ stdout, stderr, status = docker_gateway.run_shell_command(command)
24
+ return [stdout, stderr] if status.success?
25
+ raise RemoteSSHCommandError, status
26
+ end
27
+
28
+ def docker_gateway
29
+ @docker_gateway ||= DockerGateway.new(method(:log))
30
+ end
31
+ end
32
+
33
+ World(RemoteSSHHelpers)
@@ -26,6 +26,7 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
26
26
  after "deploy:new_release_path", "git:create_release"
27
27
  before "deploy:check", "git:check"
28
28
  before "deploy:set_current_revision", "git:set_current_revision"
29
+ before "deploy:set_current_revision_time", "git:set_current_revision_time"
29
30
  end
30
31
 
31
32
  def define_tasks
@@ -78,6 +79,10 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
78
79
  backend.capture(:git, "rev-list --max-count=1 #{fetch(:branch)}")
79
80
  end
80
81
 
82
+ def fetch_revision_time
83
+ backend.capture(:git, "log -1 --pretty=format:\"%ct\" #{fetch(:branch)}")
84
+ end
85
+
81
86
  def git(*args)
82
87
  args.unshift :git
83
88
  backend.execute(*args)
@@ -70,4 +70,15 @@ namespace :git do
70
70
  end
71
71
  end
72
72
  end
73
+
74
+ desc "Determine the unix timestamp that the revision that will be deployed was created"
75
+ task :set_current_revision_time do
76
+ on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
77
+ within repo_path do
78
+ with fetch(:git_environmental_variables) do
79
+ set :current_revision_time, git_plugin.fetch_revision_time
80
+ end
81
+ end
82
+ end
83
+ end
73
84
  end
@@ -3,6 +3,7 @@ namespace :deploy do
3
3
  invoke "deploy:print_config_variables" if fetch(:print_config_variables, false)
4
4
  invoke "deploy:check"
5
5
  invoke "deploy:set_previous_revision"
6
+ invoke "deploy:set_previous_revision_time"
6
7
  end
7
8
 
8
9
  task :print_config_variables do
@@ -27,6 +28,7 @@ namespace :deploy do
27
28
 
28
29
  task updating: :new_release_path do
29
30
  invoke "deploy:set_current_revision"
31
+ invoke "deploy:set_current_revision_time"
30
32
  invoke "deploy:symlink:shared"
31
33
  end
32
34
 
@@ -236,7 +238,7 @@ namespace :deploy do
236
238
  end
237
239
 
238
240
  desc "Place a REVISION file with the current revision SHA in the current release path"
239
- task :set_current_revision do
241
+ task :set_current_revision do
240
242
  on release_roles(:all) do
241
243
  within release_path do
242
244
  execute :echo, "\"#{fetch(:current_revision)}\" > REVISION"
@@ -253,6 +255,26 @@ namespace :deploy do
253
255
  end
254
256
  end
255
257
 
258
+ desc "Place a REVISION_TIME file with the current revision commit time in the current release path"
259
+ task :set_current_revision_time do
260
+ on release_roles(:all) do
261
+ within release_path do
262
+ if fetch(:current_revision_time)
263
+ execute :echo, "\"#{fetch(:current_revision_time)}\" > REVISION_TIME"
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ task :set_previous_revision_time do
270
+ on release_roles(:all) do
271
+ target = release_path.join("REVISION_TIME")
272
+ if test "[ -f #{target} ]"
273
+ set(:previous_revision_time, capture(:cat, target, "2>/dev/null"))
274
+ end
275
+ end
276
+ end
277
+
256
278
  task :restart
257
279
  task :failed
258
280
  end
@@ -1,3 +1,3 @@
1
1
  module Capistrano
2
- VERSION = "3.18.1".freeze
2
+ VERSION = "3.19.0".freeze
3
3
  end
@@ -592,8 +592,8 @@ describe Capistrano::DSL do
592
592
 
593
593
  it "yields the properties for a single role" do
594
594
  recipient = mock("recipient")
595
- recipient.expects(:doit).with("example1.com", :redis, port: 6379, type: :slave)
596
- recipient.expects(:doit).with("example2.com", :redis, port: 6379, type: :master)
595
+ recipient.expects(:doit).with("example1.com", :redis, { port: 6379, type: :slave })
596
+ recipient.expects(:doit).with("example2.com", :redis, { port: 6379, type: :master })
597
597
  dsl.role_properties(:redis) do |host, role, props|
598
598
  recipient.doit(host, role, props)
599
599
  end
@@ -601,8 +601,8 @@ describe Capistrano::DSL do
601
601
 
602
602
  it "yields the properties for multiple roles" do
603
603
  recipient = mock("recipient")
604
- recipient.expects(:doit).with("example1.com", :redis, port: 6379, type: :slave)
605
- recipient.expects(:doit).with("example2.com", :redis, port: 6379, type: :master)
604
+ recipient.expects(:doit).with("example1.com", :redis, { port: 6379, type: :slave })
605
+ recipient.expects(:doit).with("example2.com", :redis, { port: 6379, type: :master })
606
606
  recipient.expects(:doit).with("example3.com", :app, nil)
607
607
  dsl.role_properties(:redis, :app) do |host, role, props|
608
608
  recipient.doit(host, role, props)
@@ -611,10 +611,10 @@ describe Capistrano::DSL do
611
611
 
612
612
  it "yields the merged properties for multiple roles" do
613
613
  recipient = mock("recipient")
614
- recipient.expects(:doit).with("example1.com", :redis, port: 6379, type: :slave)
615
- recipient.expects(:doit).with("example2.com", :redis, port: 6379, type: :master)
616
- recipient.expects(:doit).with("example1.com", :web, port: 80)
617
- recipient.expects(:doit).with("example2.com", :web, port: 81)
614
+ recipient.expects(:doit).with("example1.com", :redis, { port: 6379, type: :slave })
615
+ recipient.expects(:doit).with("example2.com", :redis, { port: 6379, type: :master })
616
+ recipient.expects(:doit).with("example1.com", :web, { port: 80 })
617
+ recipient.expects(:doit).with("example2.com", :web, { port: 81 })
618
618
  dsl.role_properties(:redis, :web) do |host, role, props|
619
619
  recipient.doit(host, role, props)
620
620
  end
@@ -622,8 +622,8 @@ describe Capistrano::DSL do
622
622
 
623
623
  it "honours a property filter before yielding" do
624
624
  recipient = mock("recipient")
625
- recipient.expects(:doit).with("example1.com", :redis, port: 6379, type: :slave)
626
- recipient.expects(:doit).with("example1.com", :web, port: 80)
625
+ recipient.expects(:doit).with("example1.com", :redis, { port: 6379, type: :slave })
626
+ recipient.expects(:doit).with("example1.com", :web, { port: 80 })
627
627
  dsl.role_properties(:redis, :web, select: :active) do |host, role, props|
628
628
  recipient.doit(host, role, props)
629
629
  end
@@ -12,6 +12,7 @@ module Capistrano
12
12
  Rake::Task.define_task("deploy:check")
13
13
  Rake::Task.define_task("deploy:new_release_path")
14
14
  Rake::Task.define_task("deploy:set_current_revision")
15
+ Rake::Task.define_task("deploy:set_current_revision_time")
15
16
  set :scm, SCMResolver::DEFAULT_GIT
16
17
  end
17
18
 
@@ -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.
@@ -170,6 +171,15 @@ module Capistrano
170
171
  end
171
172
  end
172
173
 
174
+ describe "#fetch_revision_time" do
175
+ it "should capture git log" do
176
+ env.set(:branch, "branch")
177
+ backend.expects(:capture).with(:git, "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
+
173
183
  describe "#verify_commit" do
174
184
  it "should run git verify-commit" do
175
185
  env.set(:branch, "branch")
@@ -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
@@ -14,8 +15,8 @@ module TestApp
14
15
  set :deploy_to, '#{deploy_to}'
15
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,10 +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 "source 'https://rubygems.org'\n"
44
- file.write "gem 'capistrano', path: '#{path_to_cap}'"
45
- 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
46
50
 
47
51
  Dir.chdir(test_app_path) do
48
52
  run "bundle"
@@ -96,13 +100,12 @@ module TestApp
96
100
  end
97
101
 
98
102
  def run(command, subdirectory=nil)
99
- output = nil
100
103
  command = "bundle exec #{command}" unless command =~ /^bundle\b/
101
104
  dir = subdirectory ? test_app_path.join(subdirectory) : test_app_path
102
- Dir.chdir(dir) do
103
- output = with_clean_bundler_env { `#{command}` }
105
+ output, status = Dir.chdir(dir) do
106
+ with_clean_bundler_env { Open3.capture2e(command) }
104
107
  end
105
- [$CHILD_STATUS.success?, output]
108
+ [status.success?, output]
106
109
  end
107
110
 
108
111
  def stage
@@ -118,7 +121,7 @@ module TestApp
118
121
  end
119
122
 
120
123
  def deploy_to
121
- Pathname.new("/home/vagrant/var/www/deploy")
124
+ Pathname.new("/home/deployer/var/www/deploy")
122
125
  end
123
126
 
124
127
  def shared_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.18.1
4
+ version: 3.19.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: 2024-03-10 00:00:00.000000000 Z
12
+ date: 2024-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: airbrussh
@@ -78,6 +78,10 @@ executables:
78
78
  extensions: []
79
79
  extra_rdoc_files: []
80
80
  files:
81
+ - ".docker/Dockerfile"
82
+ - ".docker/ssh_key_rsa"
83
+ - ".docker/ssh_key_rsa.pub"
84
+ - ".docker/ubuntu_setup.sh"
81
85
  - ".github/issue_template.md"
82
86
  - ".github/pull_request_template.md"
83
87
  - ".github/release-drafter.yml"
@@ -88,7 +92,6 @@ files:
88
92
  - CHANGELOG.md
89
93
  - CONTRIBUTING.md
90
94
  - DEVELOPMENT.md
91
- - Dangerfile
92
95
  - Gemfile
93
96
  - LICENSE.txt
94
97
  - README.md
@@ -98,6 +101,7 @@ files:
98
101
  - bin/cap
99
102
  - bin/capify
100
103
  - capistrano.gemspec
104
+ - docker-compose.yml
101
105
  - features/configuration.feature
102
106
  - features/deploy.feature
103
107
  - features/deploy_failure.feature
@@ -109,9 +113,10 @@ files:
109
113
  - features/step_definitions/cap_commands.rb
110
114
  - features/step_definitions/setup.rb
111
115
  - features/subdirectory.feature
116
+ - features/support/docker_gateway.rb
112
117
  - features/support/env.rb
113
118
  - features/support/remote_command_helpers.rb
114
- - features/support/vagrant_helpers.rb
119
+ - features/support/remote_ssh_helpers.rb
115
120
  - lib/Capfile
116
121
  - lib/capistrano.rb
117
122
  - lib/capistrano/all.rb
@@ -202,8 +207,6 @@ files:
202
207
  - spec/lib/capistrano/version_validator_spec.rb
203
208
  - spec/lib/capistrano_spec.rb
204
209
  - spec/spec_helper.rb
205
- - spec/support/.gitignore
206
- - spec/support/Vagrantfile
207
210
  - spec/support/matchers.rb
208
211
  - spec/support/tasks/database.rake
209
212
  - spec/support/tasks/fail.rake
@@ -235,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
238
  - !ruby/object:Gem::Version
236
239
  version: '0'
237
240
  requirements: []
238
- rubygems_version: 3.5.6
241
+ rubygems_version: 3.5.8
239
242
  signing_key:
240
243
  specification_version: 4
241
244
  summary: Capistrano - Welcome to easy deployment with Ruby over SSH
@@ -251,9 +254,10 @@ test_files:
251
254
  - features/step_definitions/cap_commands.rb
252
255
  - features/step_definitions/setup.rb
253
256
  - features/subdirectory.feature
257
+ - features/support/docker_gateway.rb
254
258
  - features/support/env.rb
255
259
  - features/support/remote_command_helpers.rb
256
- - features/support/vagrant_helpers.rb
260
+ - features/support/remote_ssh_helpers.rb
257
261
  - spec/integration/dsl_spec.rb
258
262
  - spec/integration_spec_helper.rb
259
263
  - spec/lib/capistrano/application_spec.rb
@@ -286,8 +290,6 @@ test_files:
286
290
  - spec/lib/capistrano/version_validator_spec.rb
287
291
  - spec/lib/capistrano_spec.rb
288
292
  - spec/spec_helper.rb
289
- - spec/support/.gitignore
290
- - spec/support/Vagrantfile
291
293
  - spec/support/matchers.rb
292
294
  - spec/support/tasks/database.rake
293
295
  - spec/support/tasks/fail.rake
data/Dangerfile DELETED
@@ -1 +0,0 @@
1
- danger.import_dangerfile(github: "capistrano/danger", branch: "no-changelog")
@@ -1,41 +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
-
34
- def puts(message)
35
- # Attach log messages to the current cucumber feature (`log`),
36
- # or simply puts to the console (`super`) if we are outside of cucumber.
37
- respond_to?(:log) ? log(message) : super(message)
38
- end
39
- end
40
-
41
- 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/bionic64"
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 = URI.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