capistrano 3.16.0 → 3.19.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) 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/release-drafter.yml +10 -2
  7. data/.github/workflows/ci.yml +80 -0
  8. data/.github/workflows/release-drafter.yml +18 -0
  9. data/.rubocop.yml +3 -3
  10. data/DEVELOPMENT.md +5 -20
  11. data/Gemfile +9 -4
  12. data/README.md +2 -2
  13. data/Rakefile +9 -6
  14. data/capistrano.gemspec +0 -4
  15. data/docker-compose.yml +8 -0
  16. data/features/deploy.feature +5 -1
  17. data/features/sshconnect.feature +1 -1
  18. data/features/step_definitions/assertions.rb +33 -23
  19. data/features/step_definitions/setup.rb +10 -13
  20. data/features/support/docker_gateway.rb +53 -0
  21. data/features/support/env.rb +0 -10
  22. data/features/support/remote_command_helpers.rb +3 -3
  23. data/features/support/remote_ssh_helpers.rb +33 -0
  24. data/lib/capistrano/configuration/validated_variables.rb +1 -1
  25. data/lib/capistrano/doctor/variables_doctor.rb +2 -0
  26. data/lib/capistrano/scm/git.rb +5 -0
  27. data/lib/capistrano/scm/tasks/git.rake +11 -0
  28. data/lib/capistrano/tasks/deploy.rake +23 -1
  29. data/lib/capistrano/templates/deploy.rb.erb +2 -2
  30. data/lib/capistrano/version.rb +1 -1
  31. data/spec/integration/dsl_spec.rb +11 -11
  32. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +1 -0
  33. data/spec/lib/capistrano/dsl_spec.rb +2 -2
  34. data/spec/lib/capistrano/scm/git_spec.rb +10 -0
  35. data/spec/support/test_app.rb +15 -11
  36. metadata +14 -54
  37. data/.github/workflows/push.yml +0 -12
  38. data/.travis.yml +0 -30
  39. data/Dangerfile +0 -1
  40. data/features/support/vagrant_helpers.rb +0 -41
  41. data/spec/support/.gitignore +0 -1
  42. data/spec/support/Vagrantfile +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34b4f8bf408d7e3aeeb3adcb61a44af437f1015c2206d41dae97602445411558
4
- data.tar.gz: 99d880dedf50994b9e8ac61d43ed3ad5a7a2e11a84269a085f59bc463aff3407
3
+ metadata.gz: 1e00f29cd54bf8ffea1fdaf725fc260c3bdcf12290dda825a76c518d62fd86cf
4
+ data.tar.gz: bafa1c5c53bb543df6a583ac12d449232abc1900c572e4166f2ab51f5e2889b4
5
5
  SHA512:
6
- metadata.gz: b07d663529584f6a0fb8b324f55cc4033eabb6812d7212e8dfc5dff4c84a2c6afd038341070811370d92bbbff5fbc93836118e3d5be949a48b47e1c7af5099cf
7
- data.tar.gz: a0cd52b0c258c527320fec4057b98014856ebbecebfe187ac29f88f3c562843882457cfcfb33addfe2c17a4c6d0b4b3af625941812ef9bf779998cc4d1aa6cb3
6
+ metadata.gz: f5d0e2ef2a9786a926c67480cb5a397e9c0dee02bcb99b1719026b1fad440912f245953e595c00c284378c5ae6e2b03732754c3f72cd3dbcf7af9db6374efa2d
7
+ data.tar.gz: feee6f4862320a9db782639a74db9b7d64a614ed8803193b2463c44246ce07270f061c3f16ec9c1e6f5a50a6d3ce29fc1fa6f18b90e612a148fe1bc233b79213
@@ -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
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
3
+ NhAAAAAwEAAQAAAgEAusFQqAThmEuan12Roio7oe0VhMZc60NRppfGdwwwoIEhIm4dVlyV
4
+ PfqzSk6h5laBst+omqz347BlsNyG4lojDlw+3K4NwQskW5LAHa1VfzCKugYiqpxmkLzlfQ
5
+ BOUWwOluP6a5BCi/7XZ6VWlqTG7bYRKOh/yDtyIfol6Jp4uDZFAYw4yX+rK/Af7yOGiHKd
6
+ COf7lzSN8yFlYUOsgWeITkbPIzwTKXu4zKBW+c/LegFFH5iHOuiYi5i19oamBK3iAe685T
7
+ zrA7DgcgA7m8gP6982GgOZGcS2x0/rIEIrY2+EwE3aAsV+vrrcVUHkWSuGKwkdw/2ls4Zj
8
+ oJeTh8TuwK1oCAlwtfInK7w3VAAsTlikWkntFl8NJ19S9GbXirmLLxQH9LdJzT0rZ1pMc0
9
+ QOLJ8yQoqbblnI8fKe1mND4duuxEavazRYDA5krB2mDDpyQF6/FhdNMxXFYAFum9zASUpg
10
+ RLXM+OUbzA7+F4jL82Yj/9fsHviVyNX+WPC4clbZHjBOSe7ui6zVCOW7wTMg6HTJJjqJ0X
11
+ aS+IsDlF8KRE1+4vH7K+/vGBcPibV0NInj6uFdj5pjzV04ZY4ZIQqJ8FZxrH1eKn7hmhiY
12
+ DCiXyvxOoRfFvXoxB/Qb5l+5e+X8gCtMzKvp+qITq+DOMFXM/RvrPub0meSTcGE8lawLYb
13
+ cAAAdIBF9hmQRfYZkAAAAHc3NoLXJzYQAAAgEAusFQqAThmEuan12Roio7oe0VhMZc60NR
14
+ ppfGdwwwoIEhIm4dVlyVPfqzSk6h5laBst+omqz347BlsNyG4lojDlw+3K4NwQskW5LAHa
15
+ 1VfzCKugYiqpxmkLzlfQBOUWwOluP6a5BCi/7XZ6VWlqTG7bYRKOh/yDtyIfol6Jp4uDZF
16
+ AYw4yX+rK/Af7yOGiHKdCOf7lzSN8yFlYUOsgWeITkbPIzwTKXu4zKBW+c/LegFFH5iHOu
17
+ iYi5i19oamBK3iAe685TzrA7DgcgA7m8gP6982GgOZGcS2x0/rIEIrY2+EwE3aAsV+vrrc
18
+ VUHkWSuGKwkdw/2ls4ZjoJeTh8TuwK1oCAlwtfInK7w3VAAsTlikWkntFl8NJ19S9GbXir
19
+ mLLxQH9LdJzT0rZ1pMc0QOLJ8yQoqbblnI8fKe1mND4duuxEavazRYDA5krB2mDDpyQF6/
20
+ FhdNMxXFYAFum9zASUpgRLXM+OUbzA7+F4jL82Yj/9fsHviVyNX+WPC4clbZHjBOSe7ui6
21
+ zVCOW7wTMg6HTJJjqJ0XaS+IsDlF8KRE1+4vH7K+/vGBcPibV0NInj6uFdj5pjzV04ZY4Z
22
+ IQqJ8FZxrH1eKn7hmhiYDCiXyvxOoRfFvXoxB/Qb5l+5e+X8gCtMzKvp+qITq+DOMFXM/R
23
+ vrPub0meSTcGE8lawLYbcAAAADAQABAAACAHJNBP+A1U4v37fwPcUh0hOeFpCIE7DOJ/gt
24
+ ZoPQSybBQbVf7cbArXscqIUvMTnX8lO3PetFOAb8HJEtt8Rr5I7SeIr6YGKpXhxJ6hl/0B
25
+ cjb5TBUpBXXxLw+ggSmtyMpTVG3SreRUyHsfC2qhNTUImG6GPAQQ0dDRKslm0RthcQ6BU1
26
+ bEAvSmV+9xyXAq0acPBVg4+c09BdvT3VfIxLAIrgHcDz8Mpv9cAP1ovY2TGX+2WGJiYw28
27
+ R8t8nlyVCN2AjUxHoNWc2NgSFk8Ra8ULpNiEBNuXOjCTddu4un1ARs6bQFMgyGMbesiFQK
28
+ GydUUy6dysD8ymDhPLK6csojBviMLZNHL9Ie0aZrfazjrMDSAVX6XAVBhmXCyvyX/S0ML9
29
+ tuqljMdy6ZMzajydVhoIx5JqEtCmTqzOdx2ZSxO9KDG/JrekDz+m7G1cM4dHfhL95Qizi+
30
+ D4Ps0Mmu+fox1MJ2I+gbDMcKjoq3y1aDKdMt2ptohGNv+q9qDhuNZlmrPfzfpeEOrskNAi
31
+ zv3BHXnIBauteGNTyEakZP6YtILhuKeH78SpLPR1MFcUfcOYGfmAo7HtMMFTX9eRWg80Is
32
+ ErOHjuFsy99IvLS9U+jnX0qnKEPH4uhzOzh+Ce6Vmel67eeDoLL1CzA6Mk2ag+/akVduVU
33
+ T5p7sZY1/aa0XBU+ShAAABAE59lZ/rH+XAkGQ/TGVo/M119xaDkupkhLxbbsUPQroCtpwE
34
+ DiZCyyjGZ/SMXJAr8pnnXj0z6VB83R3ds3fCTAcoVM/DaB2kjvlTXGLr1hAs3SqPnw9hyr
35
+ wfRWM06GGSHB6a8Bt79jxHF9tsnI6wlrV6XUmCkhFFLyPyvNMDANZpd3J+mowVeq+vWTn5
36
+ D49EAmdSCQeEzTOPIfa5PLpaoaDHLSYgfc+xrotZG947WhOQwSr+6T7Ak1A4mhAQcc1Nqu
37
+ q1bzou+BnlTNMFQ4jv1j8ZLDSYoUozvPIGU92CP7Y6x+OCAXfzgX+BlrZla5adLDzmJZSZ
38
+ zxkxWlPCUaBD14cAAAEBAOmOjI8mZrizzziMYLEqa+RFo1ZKzRiKk2c5XY5gsSnF97pora
39
+ i0OynfaOWgiWiVPi7YUPpHynYwHz696E4gEzR1YjZR32oYOd6OoEJLv9zb522yxaK6aIY0
40
+ hjooFFYBbSEEPxc7Ui2YSCXFwKdxxmfVYxX5C6d0AJVAtFSG+lSQNgIwp8J3VOs178mru/
41
+ pr1r5+XiEBHrCszPuCCayNeA8dlS8NZoV0KAtjEESM4MwI7P2tkiCROk+T/nWrpVMFdsKw
42
+ wQqTuBqrUUF3tMUnv90XaEO4V5Ug/a0C8UwuMA0/PbnteE/g4bfktf4twll3NWygQc/q/w
43
+ xEJWM8KFHInscAAAEBAMyzdCiid1BaDDYilyPGqQCz59Kk1dD7gFyNaz+QsqjDl1YdAxfZ
44
+ +b8xNwP9PE0AQSLYG0sU5WvQt7NktuVnSEzSjfvwEwQ5Os27ArWq0/C7iksPfAThtviwuh
45
+ +vZUyilag0gfP73wAILqKWQLfAFgGleT7qgRvtrLpNCVHFHcDRRSwjifsyBnM587CmC10B
46
+ 8AznqByEGtanaJFTbbKmpFM8t7IvOi5M/vzvYmXSVjRdKoHIZRsOgpHh/Bo9r36H5FhGQJ
47
+ IwlQSS0XwkhTE7u+o0dxlvqfrq726iEGbjJD7cHxgnKwRFkVo9g20rgpdDjv/TmX0MKm0y
48
+ +sSkqvnj9ZEAAAAQdGVzdEBleGFtcGxlLmNvbQECAw==
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
@@ -1,5 +1,5 @@
1
- name-template: "$NEXT_PATCH_VERSION"
2
- tag-template: "v$NEXT_PATCH_VERSION"
1
+ name-template: "$RESOLVED_VERSION"
2
+ tag-template: "v$RESOLVED_VERSION"
3
3
  categories:
4
4
  - title: "⚠️ Breaking Changes"
5
5
  label: "⚠️ Breaking"
@@ -11,7 +11,15 @@ categories:
11
11
  label: "📚 Docs"
12
12
  - title: "🏠 Housekeeping"
13
13
  label: "🏠 Housekeeping"
14
+ version-resolver:
15
+ minor:
16
+ labels:
17
+ - "⚠️ Breaking"
18
+ - "✨ Feature"
19
+ default: patch
14
20
  change-template: "- $TITLE (#$NUMBER) @$AUTHOR"
15
21
  no-changes-template: "- No changes"
16
22
  template: |
17
23
  $CHANGES
24
+
25
+ **Full Changelog:** https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
@@ -0,0 +1,80 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [master]
5
+ pull_request:
6
+ jobs:
7
+ spec:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ matrix:
11
+ ruby:
12
+ [
13
+ "2.3",
14
+ "2.4",
15
+ "2.5",
16
+ "2.6",
17
+ "2.7",
18
+ "3.0",
19
+ "3.1",
20
+ "3.2",
21
+ "3.3",
22
+ "head",
23
+ ]
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby }}
30
+ bundler-cache: true
31
+ - name: rake spec
32
+ run: bundle exec rake spec
33
+ spec-legacy:
34
+ runs-on: ubuntu-20.04
35
+ strategy:
36
+ matrix:
37
+ ruby: ["2.0", "2.1", "2.2"]
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - name: Set up Ruby
41
+ uses: ruby/setup-ruby@v1
42
+ with:
43
+ ruby-version: ${{ matrix.ruby }}
44
+ bundler-cache: true
45
+ - name: rake spec
46
+ run: bundle exec rake spec
47
+ spec-all:
48
+ runs-on: ubuntu-latest
49
+ needs: [spec, spec-legacy]
50
+ if: always()
51
+ steps:
52
+ - name: All tests ok
53
+ if: ${{ !(contains(needs.*.result, 'failure')) }}
54
+ run: exit 0
55
+ - name: Some tests failed
56
+ if: ${{ contains(needs.*.result, 'failure') }}
57
+ run: exit 1
58
+ rubocop:
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - uses: actions/checkout@v4
62
+ - name: Set up Ruby
63
+ uses: ruby/setup-ruby@v1
64
+ with:
65
+ ruby-version: "ruby" # latest-stable
66
+ bundler-cache: true
67
+ - name: rake rubocop
68
+ run: bundle exec rake rubocop
69
+ features:
70
+ needs: [spec, spec-legacy]
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+ - name: Set up Ruby
75
+ uses: ruby/setup-ruby@v1
76
+ with:
77
+ ruby-version: "ruby" # latest-stable
78
+ bundler-cache: true
79
+ - name: rake features
80
+ run: bundle exec rake features
@@ -0,0 +1,18 @@
1
+ name: Release Drafter
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: read
11
+
12
+ jobs:
13
+ update_release_draft:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: release-drafter/release-drafter@v5
17
+ env:
18
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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 documention 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,26 +38,17 @@ $ 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
- ### Report failing Cucumber features!
55
-
56
- Currently, the Capistrano Travis build does *not* run the Cucumber suite. This means it is possible for a failing Cucumber feature to sneak in without being noticed by our continuous integration checks.
57
-
58
- **If you come across a failing Cucumber feature, this is a bug.** Please report it by opening a GitHub issue. Or even better: do your best to fix the feature and submit a pull request!
59
-
60
45
  ## Coding guidelines
61
46
 
62
47
  This project uses [RuboCop](https://github.com/bbatsov/rubocop) to enforce standard Ruby coding guidelines.
63
48
 
64
49
  * Test that your contributions pass with `rake rubocop`
65
50
  * Rubocop is also run as part of the full test suite with `rake`
66
- * Note the Travis build will fail and your PR cannot be merged if Rubocop finds errors
51
+ * Note the CI build will fail and your PR cannot be merged if Rubocop finds errors
67
52
 
68
53
  ## Submitting a pull request
69
54
 
data/Gemfile CHANGED
@@ -3,6 +3,10 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in capistrano.gemspec
4
4
  gemspec
5
5
 
6
+ gem "mocha"
7
+ gem "rspec"
8
+ gem "rspec-core", "~> 3.4.4"
9
+
6
10
  group :cucumber do
7
11
  # Latest versions of cucumber don't support Ruby < 2.1
8
12
  # rubocop:disable Bundler/DuplicatedGem
@@ -12,8 +16,6 @@ group :cucumber do
12
16
  gem "cucumber"
13
17
  end
14
18
  # rubocop:enable Bundler/DuplicatedGem
15
- gem "rspec"
16
- gem "rspec-core", "~> 3.4.4"
17
19
  end
18
20
 
19
21
  # Latest versions of net-ssh don't support Ruby < 2.2.6
@@ -36,7 +38,10 @@ if Gem::Requirement.new("< 2.2").satisfied_by?(Gem::Version.new(RUBY_VERSION))
36
38
  gem "rake", "< 13.0.0"
37
39
  end
38
40
 
39
- # We only run danger once on a new-ish ruby; no need to install it otherwise
41
+ # We only run rubocop and its dependencies on a new-ish ruby; no need to install them otherwise
40
42
  if Gem::Requirement.new("> 2.4").satisfied_by?(Gem::Version.new(RUBY_VERSION))
41
- gem "danger"
43
+ gem "base64"
44
+ gem "psych", "< 4" # Ensures rubocop works on Ruby 3.1
45
+ gem "racc"
46
+ gem "rubocop", "0.48.1"
42
47
  end
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  # Capistrano: A deployment automation tool built on Ruby, Rake, and SSH.
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/capistrano.svg)](http://badge.fury.io/rb/capistrano) [![Build Status](https://travis-ci.org/capistrano/capistrano.svg?branch=master)](https://travis-ci.org/capistrano/capistrano) [![Code Climate](https://codeclimate.com/github/capistrano/capistrano/badges/gpa.svg)](https://codeclimate.com/github/capistrano/capistrano) [![CodersClan](https://img.shields.io/badge/get-support-blue.svg)](http://codersclan.net/?repo_id=325&source=small)
4
+ [![Gem Version](https://badge.fury.io/rb/capistrano.svg)](http://badge.fury.io/rb/capistrano) [![Build Status](https://github.com/capistrano/capistrano/actions/workflows/ci.yml/badge.svg)](https://github.com/capistrano/capistrano/actions/workflows/ci.yml) [![Code Climate](https://codeclimate.com/github/capistrano/capistrano/badges/gpa.svg)](https://codeclimate.com/github/capistrano/capistrano) [![CodersClan](https://img.shields.io/badge/get-support-blue.svg)](http://codersclan.net/?repo_id=325&source=small)
5
5
 
6
6
  Capistrano is a framework for building automated deployment scripts. Although Capistrano itself is written in Ruby, it can easily be used to deploy projects of any language or framework, be it Rails, Java, or PHP.
7
7
 
@@ -107,7 +107,7 @@ Add Capistrano to your project's Gemfile using `require: false`:
107
107
 
108
108
  ``` ruby
109
109
  group :development do
110
- gem "capistrano", "~> 3.16", require: false
110
+ gem "capistrano", "~> 3.17", require: false
111
111
  end
112
112
  ```
113
113
 
data/Rakefile CHANGED
@@ -1,16 +1,19 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "cucumber/rake/task"
3
3
  require "rspec/core/rake_task"
4
- require "rubocop/rake_task"
5
4
 
6
- task default: %i(spec rubocop)
7
- RSpec::Core::RakeTask.new
5
+ begin
6
+ require "rubocop/rake_task"
7
+ desc "Run RuboCop checks"
8
+ RuboCop::RakeTask.new
9
+ task default: %i(spec rubocop)
10
+ rescue LoadError
11
+ task default: :spec
12
+ end
8
13
 
14
+ RSpec::Core::RakeTask.new
9
15
  Cucumber::Rake::Task.new(:features)
10
16
 
11
- desc "Run RuboCop checks"
12
- RuboCop::RakeTask.new
13
-
14
17
  Rake::Task["release"].enhance do
15
18
  puts "Don't forget to publish the release on GitHub!"
16
19
  system "open https://github.com/capistrano/capistrano/releases"
data/capistrano.gemspec CHANGED
@@ -31,8 +31,4 @@ Gem::Specification.new do |gem|
31
31
  gem.add_dependency "i18n"
32
32
  gem.add_dependency "rake", ">= 10.0.0"
33
33
  gem.add_dependency "sshkit", ">= 1.9.0"
34
-
35
- gem.add_development_dependency "mocha"
36
- gem.add_development_dependency "rspec"
37
- gem.add_development_dependency "rubocop", "0.48.1"
38
34
  end
@@ -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