capistrano 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +89 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +226 -0
- data/Rakefile +5 -0
- data/bin/cap +2 -3
- data/bin/capify +7 -77
- data/capistrano-public_cert.pem +22 -0
- data/capistrano.gemspec +35 -0
- data/features/deploy.feature +52 -0
- data/features/installation.feature +16 -0
- data/features/remote_file_task.feature +14 -0
- data/features/step_definitions/assertions.rb +90 -0
- data/features/step_definitions/cap_commands.rb +8 -0
- data/features/step_definitions/setup.rb +25 -0
- data/features/support/env.rb +12 -0
- data/features/support/remote_command_helpers.rb +20 -0
- data/lib/Capfile +3 -0
- data/lib/capistrano/all.rb +16 -0
- data/lib/capistrano/application.rb +60 -0
- data/lib/capistrano/configuration/question.rb +42 -0
- data/lib/capistrano/configuration/server.rb +133 -0
- data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
- data/lib/capistrano/configuration/servers.rb +53 -58
- data/lib/capistrano/configuration.rb +84 -30
- data/lib/capistrano/console.rb +1 -0
- data/lib/capistrano/defaults.rb +13 -0
- data/lib/capistrano/deploy.rb +3 -0
- data/lib/capistrano/dotfile.rb +3 -0
- data/lib/capistrano/dsl/env.rb +64 -0
- data/lib/capistrano/dsl/paths.rb +94 -0
- data/lib/capistrano/dsl/stages.rb +15 -0
- data/lib/capistrano/dsl/task_enhancements.rb +53 -0
- data/lib/capistrano/dsl.rb +48 -0
- data/lib/capistrano/git.rb +1 -0
- data/lib/capistrano/hg.rb +1 -0
- data/lib/capistrano/i18n.rb +34 -0
- data/lib/capistrano/install.rb +1 -0
- data/lib/capistrano/setup.rb +21 -0
- data/lib/capistrano/tasks/console.rake +21 -0
- data/lib/capistrano/tasks/deploy.rake +204 -0
- data/lib/capistrano/tasks/framework.rake +67 -0
- data/lib/capistrano/tasks/git.rake +62 -0
- data/lib/capistrano/tasks/hg.rake +39 -0
- data/lib/capistrano/tasks/install.rake +39 -0
- data/lib/capistrano/templates/Capfile +26 -0
- data/lib/capistrano/templates/deploy.rb.erb +40 -0
- data/lib/capistrano/templates/stage.rb.erb +42 -0
- data/lib/capistrano/version.rb +1 -20
- data/lib/capistrano/version_validator.rb +37 -0
- data/lib/capistrano.rb +0 -2
- data/spec/integration/dsl_spec.rb +344 -0
- data/spec/integration_spec_helper.rb +7 -0
- data/spec/lib/capistrano/application_spec.rb +61 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
- data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
- data/spec/lib/capistrano/configuration_spec.rb +101 -0
- data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
- data/spec/lib/capistrano/dsl_spec.rb +63 -0
- data/spec/lib/capistrano/version_validator_spec.rb +103 -0
- data/spec/lib/capistrano_spec.rb +8 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/.gitignore +1 -0
- data/spec/support/Vagrantfile +13 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/support/tasks/database.cap +11 -0
- data/spec/support/test_app.rb +138 -0
- metadata +251 -179
- data/CHANGELOG +0 -512
- data/MIT-LICENSE +0 -20
- data/README +0 -43
- data/examples/sample.rb +0 -14
- data/lib/capistrano/callback.rb +0 -45
- data/lib/capistrano/cli/execute.rb +0 -82
- data/lib/capistrano/cli/help.rb +0 -102
- data/lib/capistrano/cli/help.txt +0 -53
- data/lib/capistrano/cli/options.rb +0 -183
- data/lib/capistrano/cli/ui.rb +0 -28
- data/lib/capistrano/cli.rb +0 -47
- data/lib/capistrano/command.rb +0 -161
- data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
- data/lib/capistrano/configuration/actions/inspect.rb +0 -46
- data/lib/capistrano/configuration/actions/invocation.rb +0 -134
- data/lib/capistrano/configuration/callbacks.rb +0 -148
- data/lib/capistrano/configuration/connections.rb +0 -159
- data/lib/capistrano/configuration/execution.rb +0 -126
- data/lib/capistrano/configuration/loading.rb +0 -198
- data/lib/capistrano/configuration/namespaces.rb +0 -196
- data/lib/capistrano/configuration/roles.rb +0 -51
- data/lib/capistrano/configuration/variables.rb +0 -127
- data/lib/capistrano/errors.rb +0 -15
- data/lib/capistrano/extensions.rb +0 -57
- data/lib/capistrano/gateway.rb +0 -131
- data/lib/capistrano/logger.rb +0 -59
- data/lib/capistrano/recipes/compat.rb +0 -32
- data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
- data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
- data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
- data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
- data/lib/capistrano/recipes/deploy/scm.rb +0 -19
- data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
- data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
- data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/deploy.rb +0 -494
- data/lib/capistrano/recipes/standard.rb +0 -37
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/upgrade.rb +0 -33
- data/lib/capistrano/server_definition.rb +0 -51
- data/lib/capistrano/shell.rb +0 -256
- data/lib/capistrano/ssh.rb +0 -109
- data/lib/capistrano/task_definition.rb +0 -69
- data/lib/capistrano/upload.rb +0 -146
- data/test/cli/execute_test.rb +0 -132
- data/test/cli/help_test.rb +0 -139
- data/test/cli/options_test.rb +0 -226
- data/test/cli/ui_test.rb +0 -28
- data/test/cli_test.rb +0 -17
- data/test/command_test.rb +0 -309
- data/test/configuration/actions/file_transfer_test.rb +0 -40
- data/test/configuration/actions/inspect_test.rb +0 -62
- data/test/configuration/actions/invocation_test.rb +0 -202
- data/test/configuration/callbacks_test.rb +0 -206
- data/test/configuration/connections_test.rb +0 -288
- data/test/configuration/execution_test.rb +0 -159
- data/test/configuration/loading_test.rb +0 -127
- data/test/configuration/namespace_dsl_test.rb +0 -297
- data/test/configuration/roles_test.rb +0 -47
- data/test/configuration/servers_test.rb +0 -90
- data/test/configuration/variables_test.rb +0 -180
- data/test/configuration_test.rb +0 -81
- data/test/deploy/scm/accurev_test.rb +0 -23
- data/test/deploy/scm/base_test.rb +0 -55
- data/test/deploy/scm/git_test.rb +0 -112
- data/test/deploy/strategy/copy_test.rb +0 -147
- data/test/extensions_test.rb +0 -69
- data/test/fixtures/cli_integration.rb +0 -5
- data/test/fixtures/config.rb +0 -5
- data/test/fixtures/custom.rb +0 -3
- data/test/gateway_test.rb +0 -167
- data/test/logger_test.rb +0 -123
- data/test/server_definition_test.rb +0 -108
- data/test/shell_test.rb +0 -64
- data/test/ssh_test.rb +0 -97
- data/test/task_definition_test.rb +0 -101
- data/test/upload_test.rb +0 -131
- data/test/utils.rb +0 -42
- data/test/version_test.rb +0 -24
data/README.md
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
# Capistrano [![Build Status](https://travis-ci.org/capistrano/capistrano.png?branch=v3)](https://travis-ci.org/capistrano/capistrano)
|
2
|
+
|
3
|
+
## Requirements
|
4
|
+
|
5
|
+
* Ruby >= 1.9 (JRuby and C-Ruby/YARV are supported)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
``` ruby
|
12
|
+
gem 'capistrano', '~> 3.0.0'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
$ bundle --binstubs
|
19
|
+
```
|
20
|
+
|
21
|
+
Capify:
|
22
|
+
*make sure there's no "Capfile" or "capfile" present*
|
23
|
+
``` shell
|
24
|
+
$ cap install
|
25
|
+
```
|
26
|
+
|
27
|
+
This creates the following files:
|
28
|
+
|
29
|
+
```
|
30
|
+
├── Capfile
|
31
|
+
├── config
|
32
|
+
│ ├── deploy
|
33
|
+
│ │ ├── production.rb
|
34
|
+
│ │ └── staging.rb
|
35
|
+
│ └── deploy.rb
|
36
|
+
└── lib
|
37
|
+
└── capistrano
|
38
|
+
└── tasks
|
39
|
+
```
|
40
|
+
|
41
|
+
To create different stages:
|
42
|
+
|
43
|
+
``` shell
|
44
|
+
$ cap install STAGES=local,sandbox,qa,production
|
45
|
+
```
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
``` shell
|
50
|
+
$ cap -vT
|
51
|
+
|
52
|
+
$ cap staging deploy
|
53
|
+
$ cap production deploy
|
54
|
+
|
55
|
+
$ cap production deploy --dry-run
|
56
|
+
$ cap production deploy --prereqs
|
57
|
+
$ cap production deploy --trace
|
58
|
+
```
|
59
|
+
|
60
|
+
## Tasks
|
61
|
+
|
62
|
+
``` ruby
|
63
|
+
server 'example.com', roles: [:web, :app]
|
64
|
+
server 'example.org', roles: [:db, :workers]
|
65
|
+
desc "Report Uptimes"
|
66
|
+
task :uptime do
|
67
|
+
on roles(:all) do |host|
|
68
|
+
info "Host #{host} (#{host.roles.join(', ')}):\t#{capture(:uptime)}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
## Before / After
|
74
|
+
|
75
|
+
Where calling on the same task name, executed in order of inclusion
|
76
|
+
|
77
|
+
``` ruby
|
78
|
+
# call an existing task
|
79
|
+
before :starting, :ensure_user
|
80
|
+
|
81
|
+
after :finishing, :notify
|
82
|
+
|
83
|
+
|
84
|
+
# or define in block
|
85
|
+
before :starting, :ensure_user do
|
86
|
+
#
|
87
|
+
end
|
88
|
+
|
89
|
+
after :finishing, :notify do
|
90
|
+
#
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
If it makes sense for your use-case (often, that means *generating a file*)
|
95
|
+
the Rake prerequisite mechanism can be used:
|
96
|
+
|
97
|
+
``` ruby
|
98
|
+
desc "Create Important File"
|
99
|
+
file 'important.txt' do |t|
|
100
|
+
sh "touch #{t.name}"
|
101
|
+
end
|
102
|
+
desc "Upload Important File"
|
103
|
+
task :upload => 'important.txt' do |t|
|
104
|
+
on roles(:all) do
|
105
|
+
upload!(t.prerequisites.first, '/tmp')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
The final way to call out to other tasks is to simply `invoke()` them:
|
111
|
+
|
112
|
+
``` ruby
|
113
|
+
task :one do
|
114
|
+
on roles(:all) { info "One" }
|
115
|
+
end
|
116
|
+
task :two do
|
117
|
+
invoke :one
|
118
|
+
on roles(:all) { info "Two" }
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
This method is widely used.
|
123
|
+
|
124
|
+
## Getting User Input
|
125
|
+
|
126
|
+
``` ruby
|
127
|
+
desc "Ask about breakfast"
|
128
|
+
task :breakfast do
|
129
|
+
breakfast = ask(:breakfast, "What would you like your colleagues to you for breakfast?")
|
130
|
+
on roles(:all) do |h|
|
131
|
+
execute "echo \"$(whoami) wants #{breakfast} for breakfast!\" | wall"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
```
|
135
|
+
|
136
|
+
Perfect, who needs telephones.
|
137
|
+
|
138
|
+
|
139
|
+
## Running local tasks
|
140
|
+
|
141
|
+
Local tasks can be run by replacing `on` with `run_locally`
|
142
|
+
|
143
|
+
``` ruby
|
144
|
+
desc "Notify service of deployment"
|
145
|
+
task :notify do
|
146
|
+
run_locally do
|
147
|
+
with rails_env: :development do
|
148
|
+
rake 'service:notify'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
## Console
|
155
|
+
|
156
|
+
**Note:** Here be dragons. The console is very immature, but it's much more
|
157
|
+
cleanly architected than previous incarnations and it'll only get better from
|
158
|
+
here on in.
|
159
|
+
|
160
|
+
Execute arbitrary remote commands, to use this simply add
|
161
|
+
`require 'capistrano/console'` which will add the necessary tasks to your
|
162
|
+
environment:
|
163
|
+
|
164
|
+
``` shell
|
165
|
+
$ cap staging console
|
166
|
+
```
|
167
|
+
|
168
|
+
Then, after setting up the server connections, this is how that might look:
|
169
|
+
|
170
|
+
```
|
171
|
+
$ cap production console
|
172
|
+
capistrano console - enter command to execute on production
|
173
|
+
production> uptime
|
174
|
+
INFO [94db8027] Running /usr/bin/env uptime on leehambley@example.com:22
|
175
|
+
DEBUG [94db8027] Command: /usr/bin/env uptime
|
176
|
+
DEBUG [94db8027] 17:11:17 up 50 days, 22:31, 1 user, load average: 0.02, 0.02, 0.05
|
177
|
+
INFO [94db8027] Finished in 0.435 seconds command successful.
|
178
|
+
production> who
|
179
|
+
INFO [9ce34809] Running /usr/bin/env who on leehambley@example.com:22
|
180
|
+
DEBUG [9ce34809] Command: /usr/bin/env who
|
181
|
+
DEBUG [9ce34809] leehambley pts/0 2013-06-13 17:11 (port-11262.pppoe.wtnet.de)
|
182
|
+
INFO [9ce34809] Finished in 0.420 seconds command successful.
|
183
|
+
```
|
184
|
+
|
185
|
+
## A word about PTYs
|
186
|
+
|
187
|
+
There is a configuration option which asks the backend driver to as the remote host
|
188
|
+
to assign the connection a *pty*. A *pty* is a pseudo-terminal, which in effect means
|
189
|
+
*tell the backend that this is an **interactive** session*. This is normally a bad idea.
|
190
|
+
|
191
|
+
Most of the differences are best explained by [this page](https://github.com/sstephenson/rbenv/wiki/Unix-shell-initialization) from the author of *rbenv*.
|
192
|
+
|
193
|
+
**When Capistrano makes a connection it is a *non-login*, *non-interactive* shell.
|
194
|
+
This was not an accident!**
|
195
|
+
|
196
|
+
It's often used as a band aid to cure issues related to RVM and rbenv not loading login
|
197
|
+
and shell initialisation scripts. In these scenarios RVM and rbenv are the tools at fault,
|
198
|
+
or at least they are being used incorrectly.
|
199
|
+
|
200
|
+
Whilst, especially in the case of language runtimes (Ruby, Node, Python and friends in
|
201
|
+
particular) there is a temptation to run multiple versions in parallel on a single server
|
202
|
+
and to switch between them using environmental variables, this is an anti-pattern, and
|
203
|
+
symptomatic of bad design (i.e. you're testing a second version of Ruby in production because
|
204
|
+
your company lacks the infrastructure to test this in a staging environment).
|
205
|
+
|
206
|
+
## Configuration
|
207
|
+
|
208
|
+
The following variables are settable:
|
209
|
+
|
210
|
+
| Variable Name | Description | Notes |
|
211
|
+
|:---------------------:|---------------------------------------------------------------------|-----------------------------------------------------------------|
|
212
|
+
| `:repo_url` | The URL of your Git repository | file://, https://, or ssh:// are all supported |
|
213
|
+
| `:git_https_username` | The (optional) username for accessing your Git repostory over HTTPS | if this is an SSH connection, this setting will have no effect. |
|
214
|
+
| `:git_https_password` | The (optional) password for accessing your Git repostory over HTTPS | if this is an SSH connection, this setting will have no effect. |
|
215
|
+
| `:tmp_dir` | The (optional) temp directory that will be used (default: /tmp) | if you have a shared web host, this setting may need to be set (i.e. /home/user/tmp/capistrano). |
|
216
|
+
|
217
|
+
## SSHKit
|
218
|
+
|
219
|
+
[SSHKit](https://github.com/capistrano/sshkit) is the driver for SSH
|
220
|
+
connections behind the scenes in Capistrano, depending how deep you dig, you
|
221
|
+
might run into interfaces that come directly from SSHKit (the configuration is
|
222
|
+
a good example).
|
223
|
+
|
224
|
+
## Licence
|
225
|
+
|
226
|
+
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Capistrano</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://www.capistranorb.com." property="cc:attributionName" rel="cc:attributionURL">Lee Hambley and Tom Clements</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://www.github.com/capistrano" rel="dct:source">https://www.github.com/capistrano</a>.
|
data/Rakefile
ADDED
data/bin/cap
CHANGED
data/bin/capify
CHANGED
@@ -1,78 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
puts opts
|
10
|
-
exit 0
|
11
|
-
end
|
12
|
-
|
13
|
-
begin
|
14
|
-
opts.parse!(ARGV)
|
15
|
-
rescue OptionParser::ParseError => e
|
16
|
-
warn e.message
|
17
|
-
puts opts
|
18
|
-
exit 1
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
if ARGV.empty?
|
23
|
-
abort "Please specify the directory to capify, e.g. `#{File.basename($0)} .'"
|
24
|
-
elsif !File.exists?(ARGV.first)
|
25
|
-
abort "`#{ARGV.first}' does not exist."
|
26
|
-
elsif !File.directory?(ARGV.first)
|
27
|
-
abort "`#{ARGV.first}' is not a directory."
|
28
|
-
elsif ARGV.length > 1
|
29
|
-
abort "Too many arguments; please specify only the directory to capify."
|
30
|
-
end
|
31
|
-
|
32
|
-
def unindent(string)
|
33
|
-
indentation = string[/\A\s*/]
|
34
|
-
string.strip.gsub(/^#{indentation}/, "")
|
35
|
-
end
|
36
|
-
|
37
|
-
files = {
|
38
|
-
"Capfile" => unindent(<<-FILE),
|
39
|
-
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
|
40
|
-
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
|
41
|
-
load 'config/deploy'
|
42
|
-
FILE
|
43
|
-
|
44
|
-
"config/deploy.rb" => unindent(<<-FILE),
|
45
|
-
set :application, "set your application name here"
|
46
|
-
set :repository, "set your repository location here"
|
47
|
-
|
48
|
-
# If you aren't deploying to /u/apps/\#{application} on the target
|
49
|
-
# servers (which is the default), you can specify the actual location
|
50
|
-
# via the :deploy_to variable:
|
51
|
-
# set :deploy_to, "/var/www/\#{application}"
|
52
|
-
|
53
|
-
# If you aren't using Subversion to manage your source code, specify
|
54
|
-
# your SCM below:
|
55
|
-
# set :scm, :subversion
|
56
|
-
|
57
|
-
role :app, "your app-server here"
|
58
|
-
role :web, "your web-server here"
|
59
|
-
role :db, "your db-server here", :primary => true
|
60
|
-
FILE
|
61
|
-
}
|
62
|
-
|
63
|
-
base = ARGV.shift
|
64
|
-
files.each do |file, content|
|
65
|
-
file = File.join(base, file)
|
66
|
-
if File.exists?(file)
|
67
|
-
warn "[skip] `#{file}' already exists"
|
68
|
-
elsif File.exists?(file.downcase)
|
69
|
-
warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
|
70
|
-
elsif !File.exists?(File.dirname(file))
|
71
|
-
warn "[skip] directory `#{File.dirname(file)}' does not exist"
|
72
|
-
else
|
73
|
-
puts "[add] writing `#{file}'"
|
74
|
-
File.open(file, "w") { |f| f.write(content) }
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
puts "[done] capified!"
|
2
|
+
puts "-" * 80
|
3
|
+
puts "Capistrano 3.x is incompatible with Capistrano 2.x. "
|
4
|
+
puts
|
5
|
+
puts "This command has become `cap install` in Capistrano 3.x"
|
6
|
+
puts
|
7
|
+
puts "For more information see http://www.capistranorb.com/"
|
8
|
+
puts "-" * 80
|
@@ -0,0 +1,22 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDkjCCAnqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMRIwEAYDVQQDDAlnZW1t
|
3
|
+
YXN0ZXIxHDAaBgoJkiaJk/IsZAEZFgxjYXBpc3RyYW5vcmIxEzARBgoJkiaJk/Is
|
4
|
+
ZAEZFgNjb20wHhcNMTMwNjI4MTM0MzQ1WhcNMTQwNjI4MTM0MzQ1WjBHMRIwEAYD
|
5
|
+
VQQDDAlnZW1tYXN0ZXIxHDAaBgoJkiaJk/IsZAEZFgxjYXBpc3RyYW5vcmIxEzAR
|
6
|
+
BgoJkiaJk/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
7
|
+
AQDnuMT+SoCTQoxEOma65Vf9ftibHTzfaZPGSNcheguiFa3/Mc69/xurtUa7bGY8
|
8
|
+
ZyuJbd2pb4pqhx7PcVlByJnBQCmOHzZPzn6wVa5n4n8/VBccYcFNePdPj8+KK13x
|
9
|
+
+97E6mjNZJtf4BZm4tZD6Ztyq90+mQ0WeoseYfYdm+ZJ9BNFdB2EHmTnh983MHMj
|
10
|
+
WNn52ZC2pAHDRuxKAOj5yq8IZWA8B/IWNjMXQCJbM9eaH0+vVvquC2RyprpkfoqQ
|
11
|
+
Xb7BJA2hftizHUMk4LOldNvy220GHjKL0Ot7tlGcD2DzaZNN0aPUfezz306ytsMp
|
12
|
+
KDYYLbLcg63TPHFHu1fzyQG9AgMBAAGjgYgwgYUwCQYDVR0TBAIwADALBgNVHQ8E
|
13
|
+
BAMCBLAwHQYDVR0OBBYEFEzXgfsvOB8Aw2b+Md3t3O9PUGZCMCUGA1UdEQQeMByB
|
14
|
+
GmdlbW1hc3RlckBjYXBpc3RyYW5vcmIuY29tMCUGA1UdEgQeMByBGmdlbW1hc3Rl
|
15
|
+
ckBjYXBpc3RyYW5vcmIuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQCnS7Pcy/srhZCb
|
16
|
+
TrUNkCTHI4QEURAWRNYFLL9TCCl3oyKkwW6aZxarpQbJK3Es99sugsKh/sKijOIE
|
17
|
+
xhflvSNN59Zc/BETve1y0VktN+94GiQQ1F82SmRwmY2tJJD7C3jQ6Og6pX7eNBWZ
|
18
|
+
W1su8leIv8sj3o5Vdn/Le1HKVXMakFICq9HdLnIH1jW2Brfthlc2ujAg0cOU58GC
|
19
|
+
wNkME+L45pR9zggNpbBY23mlbAicPrsmybEdk9SOdaOCgxh+fyGx6Q2n0m5YAXgN
|
20
|
+
KVoU0DazqHs6BVyJaajxht4kCpPDD1wUqCvwlOQtotdwD7CCGCPdcYgf6fAp4yQZ
|
21
|
+
jC76QR6/
|
22
|
+
-----END CERTIFICATE-----
|
data/capistrano.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "capistrano"
|
8
|
+
gem.version = Capistrano::VERSION
|
9
|
+
gem.authors = ["Tom Clements", "Lee Hambley"]
|
10
|
+
gem.email = ["seenmyfate@gmail.com", "lee.hambley@gmail.com"]
|
11
|
+
gem.description = %q{Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH.}
|
12
|
+
gem.summary = %q{Capistrano - Welcome to easy deployment with Ruby over SSH}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = 'cap'
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.post_install_message = "If you're updating Capistrano from 2.x.x, we recommend you to read the upgrade guide: http://www.capistranorb.com/documentation/upgrading/"
|
21
|
+
|
22
|
+
#gem.signing_key = '/Volumes/SD Card/leehambley-private_key.pem'
|
23
|
+
#gem.cert_chain = ['capistrano-public_cert.pem', 'leehambley-public_cert.pem']
|
24
|
+
|
25
|
+
gem.add_dependency 'sshkit', '>= 0.0.23'
|
26
|
+
gem.add_dependency 'rake', '>= 10.0.0'
|
27
|
+
gem.add_dependency 'i18n'
|
28
|
+
|
29
|
+
gem.add_development_dependency 'rspec'
|
30
|
+
gem.add_development_dependency 'mocha'
|
31
|
+
gem.add_development_dependency 'vagrant', '~> 1.0.7'
|
32
|
+
gem.add_development_dependency 'kuroko'
|
33
|
+
gem.add_development_dependency 'cucumber'
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Feature: Deploy
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
And servers with the roles app and web
|
6
|
+
|
7
|
+
Scenario: Creating the repo
|
8
|
+
When I run cap "git:check"
|
9
|
+
Then references in the remote repo are listed
|
10
|
+
|
11
|
+
Scenario: Creating the directory structure
|
12
|
+
When I run cap "deploy:check:directories"
|
13
|
+
Then the shared path is created
|
14
|
+
And the releases path is created
|
15
|
+
|
16
|
+
Scenario: Creating linked directories
|
17
|
+
When I run cap "deploy:check:linked_dirs"
|
18
|
+
Then directories in :linked_dirs are created in shared
|
19
|
+
|
20
|
+
Scenario: Creating linked directories for linked files
|
21
|
+
When I run cap "deploy:check:make_linked_dirs"
|
22
|
+
Then directories referenced in :linked_files are created in shared
|
23
|
+
|
24
|
+
Scenario: Checking linked files - missing file
|
25
|
+
Given a required file
|
26
|
+
But the file does not exist
|
27
|
+
When I run cap "deploy:check:linked_files"
|
28
|
+
Then the task will exit
|
29
|
+
|
30
|
+
Scenario: Checking linked files - file exists
|
31
|
+
Given a required file
|
32
|
+
And that file exists
|
33
|
+
When I run cap "deploy:check:linked_files"
|
34
|
+
Then the task will be successful
|
35
|
+
|
36
|
+
Scenario: Creating a release
|
37
|
+
When I run cap "git:create_release" as part of a release
|
38
|
+
Then the repo is cloned
|
39
|
+
And the release is created
|
40
|
+
|
41
|
+
Scenario: Symlink linked files
|
42
|
+
When I run cap "deploy:symlink:linked_files" as part of a release
|
43
|
+
Then file symlinks are created in the new release
|
44
|
+
|
45
|
+
Scenario: Symlink linked dirs
|
46
|
+
When I run cap "deploy:symlink:linked_dirs" as part of a release
|
47
|
+
Then directory symlinks are created in the new release
|
48
|
+
|
49
|
+
Scenario: Publishing
|
50
|
+
When I run cap "deploy:symlink:release"
|
51
|
+
Then the current directory will be a symlink to the release
|
52
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Installation
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
|
6
|
+
Scenario: With default stages
|
7
|
+
When I run cap "install"
|
8
|
+
Then the deploy.rb file is created
|
9
|
+
And the default stage files are created
|
10
|
+
And the tasks folder is created
|
11
|
+
|
12
|
+
Scenario: With specified stages
|
13
|
+
When I run cap "install STAGES=qa,production"
|
14
|
+
Then the deploy.rb file is created
|
15
|
+
And the specified stage files are created
|
16
|
+
And the tasks folder is created
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Remote file task
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
And a custom task to generate a file
|
6
|
+
And servers with the roles app and web
|
7
|
+
|
8
|
+
Scenario: Where the file does not exist
|
9
|
+
When I run cap "deploy:check:linked_files"
|
10
|
+
Then it creates the file with the remote_task prerequisite
|
11
|
+
|
12
|
+
Scenario: Where the file already exists
|
13
|
+
When I run cap "deploy:check:linked_files"
|
14
|
+
Then it will not recreate the file
|
@@ -0,0 +1,90 @@
|
|
1
|
+
Then(/^references in the remote repo are listed$/) do
|
2
|
+
end
|
3
|
+
|
4
|
+
Then(/^the shared path is created$/) do
|
5
|
+
run_vagrant_command(test_dir_exists(TestApp.shared_path))
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^the releases path is created$/) do
|
9
|
+
run_vagrant_command(test_dir_exists(TestApp.releases_path))
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^directories in :linked_dirs are created in shared$/) do
|
13
|
+
TestApp.linked_dirs.each do |dir|
|
14
|
+
run_vagrant_command(test_dir_exists(TestApp.shared_path.join(dir)))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Then(/^directories referenced in :linked_files are created in shared$/) do
|
19
|
+
dirs = TestApp.linked_files.map { |path| TestApp.shared_path.join(path).dirname }
|
20
|
+
dirs.each do | dir|
|
21
|
+
run_vagrant_command(test_dir_exists(dir))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Then(/^the task will be successful$/) do
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
Then(/^the task will exit$/) do
|
30
|
+
end
|
31
|
+
|
32
|
+
Then(/^the repo is cloned$/) do
|
33
|
+
run_vagrant_command(test_dir_exists(TestApp.repo_path))
|
34
|
+
end
|
35
|
+
|
36
|
+
Then(/^the release is created$/) do
|
37
|
+
run_vagrant_command("ls -g #{TestApp.releases_path}")
|
38
|
+
end
|
39
|
+
|
40
|
+
Then(/^file symlinks are created in the new release$/) do
|
41
|
+
pending
|
42
|
+
TestApp.linked_files.each do |file|
|
43
|
+
run_vagrant_command(test_symlink_exists(TestApp.release_path.join(file)))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Then(/^directory symlinks are created in the new release$/) do
|
48
|
+
pending
|
49
|
+
TestApp.linked_dirs.each do |dir|
|
50
|
+
run_vagrant_command(test_symlink_exists(TestApp.release_path.join(dir)))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Then(/^the current directory will be a symlink to the release$/) do
|
55
|
+
run_vagrant_command(test_symlink_exists(TestApp.current_path))
|
56
|
+
end
|
57
|
+
|
58
|
+
Then(/^the deploy\.rb file is created$/) do
|
59
|
+
file = TestApp.test_app_path.join('config/deploy.rb')
|
60
|
+
expect(File.exists?(file)).to be_true
|
61
|
+
end
|
62
|
+
|
63
|
+
Then(/^the default stage files are created$/) do
|
64
|
+
staging = TestApp.test_app_path.join('config/deploy/staging.rb')
|
65
|
+
production = TestApp.test_app_path.join('config/deploy/production.rb')
|
66
|
+
expect(File.exists?(staging)).to be_true
|
67
|
+
expect(File.exists?(production)).to be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
Then(/^the tasks folder is created$/) do
|
71
|
+
path = TestApp.test_app_path.join('lib/capistrano/tasks')
|
72
|
+
expect(Dir.exists?(path)).to be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
Then(/^the specified stage files are created$/) do
|
76
|
+
qa = TestApp.test_app_path.join('config/deploy/qa.rb')
|
77
|
+
production = TestApp.test_app_path.join('config/deploy/production.rb')
|
78
|
+
expect(File.exists?(qa)).to be_true
|
79
|
+
expect(File.exists?(production)).to be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
Then(/^it creates the file with the remote_task prerequisite$/) do
|
83
|
+
TestApp.linked_files.each do |file|
|
84
|
+
run_vagrant_command(test_file_exists(TestApp.shared_path.join(file)))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Then(/^it will not recreate the file$/) do
|
89
|
+
#
|
90
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Given(/^a test app with the default configuration$/) do
|
2
|
+
TestApp.install
|
3
|
+
end
|
4
|
+
|
5
|
+
Given(/^servers with the roles app and web$/) do
|
6
|
+
vagrant_cli_command('up')
|
7
|
+
end
|
8
|
+
|
9
|
+
Given(/^a required file$/) do
|
10
|
+
end
|
11
|
+
|
12
|
+
Given(/^that file exists$/) do
|
13
|
+
run_vagrant_command("touch #{TestApp.linked_file}")
|
14
|
+
end
|
15
|
+
|
16
|
+
Given(/^the file does not exist$/) do
|
17
|
+
pending
|
18
|
+
file = TestApp.linked_file
|
19
|
+
run_vagrant_command("[ -f #{file} ] && rm #{file}")
|
20
|
+
end
|
21
|
+
|
22
|
+
Given(/^a custom task to generate a file$/) do
|
23
|
+
TestApp.copy_task_to_test_app('spec/support/tasks/database.cap')
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'kuroko'
|
2
|
+
|
3
|
+
project_root = File.expand_path('../../../', __FILE__)
|
4
|
+
vagrant_root = File.join(project_root, 'spec/support')
|
5
|
+
|
6
|
+
Kuroko.configure do |config|
|
7
|
+
config.vagrant_root = 'spec/support'
|
8
|
+
end
|
9
|
+
|
10
|
+
puts vagrant_root.inspect
|
11
|
+
|
12
|
+
require_relative '../../spec/support/test_app'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RemoteCommandHelpers
|
2
|
+
|
3
|
+
def test_dir_exists(path)
|
4
|
+
exists?('d', path)
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_symlink_exists(path)
|
8
|
+
exists?('L', path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_file_exists(path)
|
12
|
+
exists?('f', path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def exists?(type, path)
|
16
|
+
%{[ -#{type} "#{path}" ] && echo "#{path} exists." || echo "Error: #{path} does not exist."}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
World(RemoteCommandHelpers)
|
data/lib/Capfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'sshkit'
|
3
|
+
require 'sshkit/dsl'
|
4
|
+
|
5
|
+
Rake.application.options.trace = true
|
6
|
+
|
7
|
+
require 'capistrano/version'
|
8
|
+
require 'capistrano/version_validator'
|
9
|
+
require 'capistrano/i18n'
|
10
|
+
require 'capistrano/dsl'
|
11
|
+
require 'capistrano/application'
|
12
|
+
require 'capistrano/configuration'
|
13
|
+
|
14
|
+
module Capistrano
|
15
|
+
|
16
|
+
end
|