capistrano 3.16.0 → 3.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.docker/Dockerfile +7 -0
- data/.docker/ssh_key_rsa +49 -0
- data/.docker/ssh_key_rsa.pub +1 -0
- data/.docker/ubuntu_setup.sh +23 -0
- data/.github/release-drafter.yml +10 -2
- data/.github/workflows/ci.yml +80 -0
- data/.github/workflows/release-drafter.yml +18 -0
- data/.rubocop.yml +3 -3
- data/DEVELOPMENT.md +5 -20
- data/Gemfile +9 -4
- data/README.md +2 -2
- data/Rakefile +9 -6
- data/capistrano.gemspec +0 -4
- data/docker-compose.yml +8 -0
- data/features/deploy.feature +5 -1
- data/features/sshconnect.feature +1 -1
- data/features/step_definitions/assertions.rb +33 -23
- data/features/step_definitions/setup.rb +10 -13
- data/features/support/docker_gateway.rb +53 -0
- data/features/support/env.rb +0 -10
- data/features/support/remote_command_helpers.rb +3 -3
- data/features/support/remote_ssh_helpers.rb +33 -0
- data/lib/capistrano/configuration/validated_variables.rb +1 -1
- data/lib/capistrano/doctor/variables_doctor.rb +2 -0
- data/lib/capistrano/scm/git.rb +5 -0
- data/lib/capistrano/scm/tasks/git.rake +11 -0
- data/lib/capistrano/tasks/deploy.rake +23 -1
- data/lib/capistrano/templates/deploy.rb.erb +2 -2
- data/lib/capistrano/version.rb +1 -1
- data/spec/integration/dsl_spec.rb +11 -11
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +1 -0
- data/spec/lib/capistrano/dsl_spec.rb +2 -2
- data/spec/lib/capistrano/scm/git_spec.rb +10 -0
- data/spec/support/test_app.rb +15 -11
- metadata +14 -54
- data/.github/workflows/push.yml +0 -12
- data/.travis.yml +0 -30
- data/Dangerfile +0 -1
- data/features/support/vagrant_helpers.rb +0 -41
- data/spec/support/.gitignore +0 -1
- data/spec/support/Vagrantfile +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e00f29cd54bf8ffea1fdaf725fc260c3bdcf12290dda825a76c518d62fd86cf
|
4
|
+
data.tar.gz: bafa1c5c53bb543df6a583ac12d449232abc1900c572e4166f2ab51f5e2889b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5d0e2ef2a9786a926c67480cb5a397e9c0dee02bcb99b1719026b1fad440912f245953e595c00c284378c5ae6e2b03732754c3f72cd3dbcf7af9db6374efa2d
|
7
|
+
data.tar.gz: feee6f4862320a9db782639a74db9b7d64a614ed8803193b2463c44246ce07270f061c3f16ec9c1e6f5a50a6d3ce29fc1fa6f18b90e612a148fe1bc233b79213
|
data/.docker/Dockerfile
ADDED
data/.docker/ssh_key_rsa
ADDED
@@ -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
|
data/.github/release-drafter.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
name-template: "$
|
2
|
-
tag-template: "v$
|
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
|
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
|
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
|
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
|
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
|
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 "
|
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://
|
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.
|
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
|
-
|
7
|
-
|
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
|
data/docker-compose.yml
ADDED
data/features/deploy.feature
CHANGED
@@ -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
|
-
|
data/features/sshconnect.feature
CHANGED
@@ -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+\(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 {
|
122
|
-
.to raise_error(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
11
|
-
|
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
|
-
|
25
|
-
|
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
|
-
|
37
|
-
|
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
|
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 =
|
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
|
-
|
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
|
-
|
90
|
+
run_remote_ssh_command("mkdir -p #{TestApp.release_path(filename)}")
|
94
91
|
end
|