capistrano 2.1.0 → 3.0.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 +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
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
module Capistrano
|
3
|
+
module DSL
|
4
|
+
module Paths
|
5
|
+
|
6
|
+
def deploy_to
|
7
|
+
fetch(:deploy_to)
|
8
|
+
end
|
9
|
+
|
10
|
+
def deploy_path
|
11
|
+
Pathname.new(deploy_to)
|
12
|
+
end
|
13
|
+
|
14
|
+
def current_path
|
15
|
+
deploy_path.join('current')
|
16
|
+
end
|
17
|
+
|
18
|
+
def releases_path
|
19
|
+
deploy_path.join('releases')
|
20
|
+
end
|
21
|
+
|
22
|
+
def release_path
|
23
|
+
fetch(:release_path, current_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_release_path(timestamp=now)
|
27
|
+
set(:release_path, releases_path.join(timestamp))
|
28
|
+
end
|
29
|
+
|
30
|
+
def repo_url
|
31
|
+
require 'cgi'
|
32
|
+
require 'uri'
|
33
|
+
if fetch(:git_http_username) and fetch(:git_http_password)
|
34
|
+
URI.parse(fetch(:repo_url)).tap do |repo_uri|
|
35
|
+
repo_uri.user = fetch(:git_http_username)
|
36
|
+
repo_uri.password = CGI.escape(fetch(:git_http_password))
|
37
|
+
end.to_s
|
38
|
+
elsif fetch(:git_http_username)
|
39
|
+
URI.parse(fetch(:repo_url)).tap do |repo_uri|
|
40
|
+
repo_uri.user = fetch(:git_http_username)
|
41
|
+
end.to_s
|
42
|
+
else
|
43
|
+
fetch(:repo_url)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def repo_path
|
48
|
+
deploy_path.join('repo')
|
49
|
+
end
|
50
|
+
|
51
|
+
def shared_path
|
52
|
+
deploy_path.join('shared')
|
53
|
+
end
|
54
|
+
|
55
|
+
def revision_log
|
56
|
+
deploy_path.join('revisions.log')
|
57
|
+
end
|
58
|
+
|
59
|
+
def now
|
60
|
+
env.timestamp.strftime("%Y%m%d%H%M%S")
|
61
|
+
end
|
62
|
+
|
63
|
+
def asset_timestamp
|
64
|
+
env.timestamp.strftime("%Y%m%d%H%M.%S")
|
65
|
+
end
|
66
|
+
|
67
|
+
def linked_dirs(parent)
|
68
|
+
paths = fetch(:linked_dirs)
|
69
|
+
join_paths(parent, paths)
|
70
|
+
end
|
71
|
+
|
72
|
+
def linked_files(parent)
|
73
|
+
paths = fetch(:linked_files)
|
74
|
+
join_paths(parent, paths)
|
75
|
+
end
|
76
|
+
|
77
|
+
def linked_file_dirs(parent)
|
78
|
+
map_dirnames(linked_files(parent))
|
79
|
+
end
|
80
|
+
|
81
|
+
def linked_dir_parents(parent)
|
82
|
+
map_dirnames(linked_dirs(parent))
|
83
|
+
end
|
84
|
+
|
85
|
+
def join_paths(parent, paths)
|
86
|
+
paths.map { |path| parent.join(path) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def map_dirnames(paths)
|
90
|
+
paths.map { |path| path.dirname }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module TaskEnhancements
|
3
|
+
def before(task, prerequisite, *args, &block)
|
4
|
+
prerequisite = Rake::Task.define_task(prerequisite, *args, &block) if block_given?
|
5
|
+
Rake::Task[task].enhance [prerequisite]
|
6
|
+
end
|
7
|
+
|
8
|
+
def after(task, post_task, *args, &block)
|
9
|
+
post_task = Rake::Task.define_task(post_task, *args, &block) if block_given?
|
10
|
+
Rake::Task[task].enhance do
|
11
|
+
invoke(post_task)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def remote_file(task)
|
16
|
+
target_roles = task.delete(:roles) { :all }
|
17
|
+
define_remote_file_task(task, target_roles)
|
18
|
+
end
|
19
|
+
|
20
|
+
def define_remote_file_task(task, target_roles)
|
21
|
+
Rake::Task.define_task(task) do |t|
|
22
|
+
prerequisite_file = t.prerequisites.first
|
23
|
+
file = shared_path.join(t.name)
|
24
|
+
|
25
|
+
on roles(target_roles) do
|
26
|
+
unless test "[ -f #{file} ]"
|
27
|
+
info "Uploading #{prerequisite_file} to #{file}"
|
28
|
+
upload! File.open(prerequisite_file), file
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def ensure_stage
|
36
|
+
Rake::Task.define_task(:ensure_stage) do
|
37
|
+
unless stage_set?
|
38
|
+
puts t(:stage_not_set)
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def tasks_without_stage_dependency
|
45
|
+
stages + default_tasks
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_tasks
|
49
|
+
%w{install}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'capistrano/dsl/task_enhancements'
|
2
|
+
require 'capistrano/dsl/paths'
|
3
|
+
require 'capistrano/dsl/stages'
|
4
|
+
require 'capistrano/dsl/env'
|
5
|
+
|
6
|
+
module Capistrano
|
7
|
+
module DSL
|
8
|
+
include TaskEnhancements
|
9
|
+
include Env
|
10
|
+
include Paths
|
11
|
+
include Stages
|
12
|
+
|
13
|
+
def invoke(task, *args)
|
14
|
+
Rake::Task[task].invoke(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def t(key, options={})
|
18
|
+
I18n.t(key, options.merge(scope: :capistrano))
|
19
|
+
end
|
20
|
+
|
21
|
+
def scm
|
22
|
+
fetch(:scm)
|
23
|
+
end
|
24
|
+
|
25
|
+
def sudo(*args)
|
26
|
+
execute :sudo, *args
|
27
|
+
end
|
28
|
+
|
29
|
+
def revision_log_message
|
30
|
+
fetch(:revision_log_message,
|
31
|
+
t(:revision_log_message, branch: fetch(:branch), user: local_user, release: release_timestamp))
|
32
|
+
end
|
33
|
+
|
34
|
+
def rollback_log_message
|
35
|
+
t(:rollback_log_message, user: local_user, release: fetch(:rollback_timestamp))
|
36
|
+
end
|
37
|
+
|
38
|
+
def local_user
|
39
|
+
`whoami`
|
40
|
+
end
|
41
|
+
|
42
|
+
def lock(locked_version)
|
43
|
+
VersionValidator.new(locked_version).verify
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
self.extend Capistrano::DSL
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../tasks/git.rake", __FILE__)
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../tasks/hg.rake", __FILE__)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
en = {
|
4
|
+
starting: 'Starting',
|
5
|
+
capified: 'Capified',
|
6
|
+
starting: 'Starting',
|
7
|
+
start: 'Start',
|
8
|
+
update: 'Update',
|
9
|
+
finalize: 'Finalise',
|
10
|
+
restart: 'Restart',
|
11
|
+
finishing: 'Finishing',
|
12
|
+
finished: 'Finished',
|
13
|
+
stage_not_set: 'Stage not set, please call something such as `cap production deploy`, where production is a stage you have defined.',
|
14
|
+
written_file: 'create %{file}',
|
15
|
+
question: 'Please enter %{key}: |%{default_value}|',
|
16
|
+
keeping_releases: 'Keeping %{keep_releases} of %{releases} deployed releases on %{host}',
|
17
|
+
no_old_releases: 'No old releases (keeping newest %{keep_releases}) on %{host}',
|
18
|
+
linked_file_does_not_exist: 'linked file %{file} does not exist on %{host}',
|
19
|
+
mirror_exists: "The repository mirror is at %{at}",
|
20
|
+
revision_log_message: 'Branch %{branch} deployed as release %{release} by %{user}',
|
21
|
+
rollback_log_message: '%{user} rolled back to release %{release}',
|
22
|
+
console: {
|
23
|
+
welcome: 'capistrano console - enter command to execute on %{stage}',
|
24
|
+
bye: 'bye'
|
25
|
+
},
|
26
|
+
error: {
|
27
|
+
user: {
|
28
|
+
does_not_exist: 'User %{user} does not exists',
|
29
|
+
cannot_switch: 'Cannot switch to user %{user}'
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
I18n.backend.store_translations(:en, { capistrano: en })
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path(File.join(File.dirname(__FILE__),'tasks/install.rake'))
|
@@ -0,0 +1,21 @@
|
|
1
|
+
include Capistrano::DSL
|
2
|
+
|
3
|
+
namespace :load do
|
4
|
+
task :defaults do
|
5
|
+
load 'capistrano/defaults.rb'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
stages.each do |stage|
|
10
|
+
Rake::Task.define_task(stage) do
|
11
|
+
invoke 'load:defaults'
|
12
|
+
load 'config/deploy.rb'
|
13
|
+
load "config/deploy/#{stage}.rb"
|
14
|
+
load "capistrano/#{fetch(:scm)}.rb"
|
15
|
+
set(:stage, stage.to_sym)
|
16
|
+
I18n.locale = fetch(:locale, :en)
|
17
|
+
configure_backend
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'capistrano/dotfile'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
desc 'Execute remote commands'
|
2
|
+
task :console do
|
3
|
+
stage = fetch(:stage)
|
4
|
+
puts I18n.t('console.welcome', scope: :capistrano, stage: stage)
|
5
|
+
loop do
|
6
|
+
print "#{stage}> "
|
7
|
+
command = $stdin.gets.chomp
|
8
|
+
if %w{quit exit q}.include? command
|
9
|
+
puts t('console.bye')
|
10
|
+
break
|
11
|
+
else
|
12
|
+
begin
|
13
|
+
on roles :all do
|
14
|
+
execute command
|
15
|
+
end
|
16
|
+
rescue => e
|
17
|
+
puts e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
namespace :deploy do
|
2
|
+
|
3
|
+
task :starting do
|
4
|
+
invoke 'deploy:check'
|
5
|
+
end
|
6
|
+
|
7
|
+
task :updating => :new_release_path do
|
8
|
+
invoke "#{scm}:create_release"
|
9
|
+
invoke 'deploy:symlink:shared'
|
10
|
+
end
|
11
|
+
|
12
|
+
task :reverting do
|
13
|
+
invoke 'deploy:revert_release'
|
14
|
+
end
|
15
|
+
|
16
|
+
task :publishing do
|
17
|
+
invoke 'deploy:symlink:release'
|
18
|
+
invoke 'deploy:restart'
|
19
|
+
end
|
20
|
+
|
21
|
+
task :finishing do
|
22
|
+
invoke 'deploy:cleanup'
|
23
|
+
end
|
24
|
+
|
25
|
+
task :finishing_rollback do
|
26
|
+
invoke 'deploy:cleanup_rollback'
|
27
|
+
end
|
28
|
+
|
29
|
+
task :finished do
|
30
|
+
invoke 'deploy:log_revision'
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Check required files and directories exist'
|
34
|
+
task :check do
|
35
|
+
invoke "#{scm}:check"
|
36
|
+
invoke 'deploy:check:directories'
|
37
|
+
invoke 'deploy:check:linked_dirs'
|
38
|
+
invoke 'deploy:check:make_linked_dirs'
|
39
|
+
invoke 'deploy:check:linked_files'
|
40
|
+
end
|
41
|
+
|
42
|
+
namespace :check do
|
43
|
+
desc 'Check shared and release directories exist'
|
44
|
+
task :directories do
|
45
|
+
on roles :all do
|
46
|
+
execute :mkdir, '-pv', shared_path, releases_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Check directories to be linked exist in shared'
|
51
|
+
task :linked_dirs do
|
52
|
+
next unless any? :linked_dirs
|
53
|
+
on roles :app do
|
54
|
+
execute :mkdir, '-pv', linked_dirs(shared_path)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Check directories of files to be linked exist in shared'
|
59
|
+
task :make_linked_dirs do
|
60
|
+
next unless any? :linked_files
|
61
|
+
on roles :app do |host|
|
62
|
+
execute :mkdir, '-pv', linked_file_dirs(shared_path)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Check files to be linked exist in shared'
|
67
|
+
task :linked_files do
|
68
|
+
next unless any? :linked_files
|
69
|
+
on roles :app do |host|
|
70
|
+
linked_files(shared_path).each do |file|
|
71
|
+
unless test "[ -f #{file} ]"
|
72
|
+
error t(:linked_file_does_not_exist, file: file, host: host)
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
namespace :symlink do
|
81
|
+
desc 'Symlink release to current'
|
82
|
+
task :release do
|
83
|
+
on roles :all do
|
84
|
+
execute :rm, '-rf', current_path
|
85
|
+
execute :ln, '-s', release_path, current_path
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Symlink files and directories from shared to release'
|
90
|
+
task :shared do
|
91
|
+
invoke 'deploy:symlink:linked_files'
|
92
|
+
invoke 'deploy:symlink:linked_dirs'
|
93
|
+
end
|
94
|
+
|
95
|
+
desc 'Symlink linked directories'
|
96
|
+
task :linked_dirs do
|
97
|
+
next unless any? :linked_dirs
|
98
|
+
on roles :app do
|
99
|
+
execute :mkdir, '-pv', linked_dir_parents(release_path)
|
100
|
+
|
101
|
+
fetch(:linked_dirs).each do |dir|
|
102
|
+
target = release_path.join(dir)
|
103
|
+
source = shared_path.join(dir)
|
104
|
+
unless test "[ -L #{target} ]"
|
105
|
+
if test "[ -d #{target} ]"
|
106
|
+
execute :rm, '-rf', target
|
107
|
+
end
|
108
|
+
execute :ln, '-s', source, target
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
desc 'Symlink linked files'
|
115
|
+
task :linked_files do
|
116
|
+
next unless any? :linked_files
|
117
|
+
on roles :app do
|
118
|
+
execute :mkdir, '-pv', linked_file_dirs(release_path)
|
119
|
+
|
120
|
+
fetch(:linked_files).each do |file|
|
121
|
+
target = release_path.join(file)
|
122
|
+
source = shared_path.join(file)
|
123
|
+
unless test "[ -L #{target} ]"
|
124
|
+
if test "[ -f #{target} ]"
|
125
|
+
execute :rm, target
|
126
|
+
end
|
127
|
+
execute :ln, '-s', source, target
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
desc 'Clean up old releases'
|
135
|
+
task :cleanup do
|
136
|
+
on roles :all do |host|
|
137
|
+
releases = capture(:ls, '-x', releases_path).split
|
138
|
+
if releases.count >= fetch(:keep_releases)
|
139
|
+
info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: releases.count)
|
140
|
+
directories = (releases - releases.last(fetch(:keep_releases)))
|
141
|
+
if directories.any?
|
142
|
+
directories_str = directories.map do |release|
|
143
|
+
releases_path.join(release)
|
144
|
+
end.join(" ")
|
145
|
+
execute :rm, '-rf', directories_str
|
146
|
+
else
|
147
|
+
info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
desc 'Remove and archive rolled-back release.'
|
154
|
+
task :cleanup_rollback do
|
155
|
+
on roles(:all) do
|
156
|
+
last_release = capture(:ls, '-xr', releases_path).split.first
|
157
|
+
last_release_path = releases_path.join(last_release)
|
158
|
+
if test "[ `readlink #{current_path}` != #{last_release_path} ]"
|
159
|
+
execute :tar, '-czf',
|
160
|
+
deploy_path.join("rolled-back-release-#{last_release}.tar.gz"),
|
161
|
+
last_release_path
|
162
|
+
execute :rm, '-rf', last_release_path
|
163
|
+
else
|
164
|
+
debug 'Last release is the current release, skip cleanup_rollback.'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
desc 'Log details of the deploy'
|
170
|
+
task :log_revision do
|
171
|
+
on roles(:all) do
|
172
|
+
within releases_path do
|
173
|
+
execute %{echo "#{revision_log_message}" >> #{revision_log}}
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
desc 'Revert to previous release timestamp'
|
179
|
+
task :revert_release => :rollback_release_path do
|
180
|
+
on roles(:all) do
|
181
|
+
set(:revision_log_message, rollback_log_message)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
task :new_release_path do
|
186
|
+
set_release_path
|
187
|
+
end
|
188
|
+
|
189
|
+
task :last_release_path do
|
190
|
+
on roles(:all) do
|
191
|
+
last_release = capture(:ls, '-xr', releases_path).split[1]
|
192
|
+
set_release_path(last_release)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
task :rollback_release_path do
|
197
|
+
on roles(:all) do
|
198
|
+
last_release = capture(:ls, '-xr', releases_path).split[1]
|
199
|
+
set_release_path(last_release)
|
200
|
+
set(:rollback_timestamp, last_release)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
namespace :deploy do
|
2
|
+
|
3
|
+
desc 'Start a deployment, make sure server(s) ready.'
|
4
|
+
task :starting do
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Started'
|
8
|
+
task :started do
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Update server(s) by setting up a new release.'
|
12
|
+
task :updating do
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Updated'
|
16
|
+
task :updated do
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Revert server(s) to previous release.'
|
20
|
+
task :reverting do
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Reverted'
|
24
|
+
task :reverted do
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Publish the release.'
|
28
|
+
task :publishing do
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Published'
|
32
|
+
task :published do
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Finish the deployment, clean up server(s).'
|
36
|
+
task :finishing do
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Finish the rollback, clean up server(s).'
|
40
|
+
task :finishing_rollback do
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'Finished'
|
44
|
+
task :finished do
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Rollback to previous release.'
|
48
|
+
task :rollback do
|
49
|
+
%w{ starting started
|
50
|
+
reverting reverted
|
51
|
+
publishing published
|
52
|
+
finishing_rollback finished }.each do |task|
|
53
|
+
invoke "deploy:#{task}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Deploy a new release.'
|
59
|
+
task :deploy do
|
60
|
+
%w{ starting started
|
61
|
+
updating updated
|
62
|
+
publishing published
|
63
|
+
finishing finished }.each do |task|
|
64
|
+
invoke "deploy:#{task}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
task default: :deploy
|
@@ -0,0 +1,62 @@
|
|
1
|
+
namespace :git do
|
2
|
+
|
3
|
+
git_environmental_variables = {
|
4
|
+
git_askpass: "/bin/echo",
|
5
|
+
git_ssh: "#{fetch(:tmp_dir)}/git-ssh.sh"
|
6
|
+
}
|
7
|
+
|
8
|
+
desc 'Upload the git wrapper script, this script guarantees that we can script git without getting an interactive prompt'
|
9
|
+
task :wrapper do
|
10
|
+
on roles :all do
|
11
|
+
upload! StringIO.new("#!/bin/sh -e\nexec /usr/bin/ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no \"$@\"\n"), "#{fetch(:tmp_dir)}/git-ssh.sh"
|
12
|
+
execute :chmod, "+x", "#{fetch(:tmp_dir)}/git-ssh.sh"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Check that the repository is reachable'
|
17
|
+
task check: :'git:wrapper' do
|
18
|
+
fetch(:branch)
|
19
|
+
on roles :all do
|
20
|
+
with git_environmental_variables do
|
21
|
+
exit 1 unless test :git, :'ls-remote', repo_url
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Clone the repo to the cache'
|
27
|
+
task clone: :'git:wrapper' do
|
28
|
+
on roles :all do
|
29
|
+
if test " [ -f #{repo_path}/HEAD ] "
|
30
|
+
info t(:mirror_exists, at: repo_path)
|
31
|
+
else
|
32
|
+
within deploy_path do
|
33
|
+
with git_environmental_variables do
|
34
|
+
execute :git, :clone, '--mirror', repo_url, repo_path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Update the repo mirror to reflect the origin state'
|
42
|
+
task update: :'git:clone' do
|
43
|
+
on roles :all do
|
44
|
+
within repo_path do
|
45
|
+
execute :git, :remote, :update
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Copy repo to releases'
|
51
|
+
task create_release: :'git:update' do
|
52
|
+
on roles :all do
|
53
|
+
with git_environmental_variables do
|
54
|
+
within repo_path do
|
55
|
+
execute :mkdir, '-p', release_path
|
56
|
+
execute :git, :archive, fetch(:branch), '| tar -x -C', release_path
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
namespace :hg do
|
2
|
+
desc 'Check that the repo is reachable'
|
3
|
+
task :check do
|
4
|
+
on roles :all do
|
5
|
+
execute "hg", "id", repo_url
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'Clone the repo to the cache'
|
10
|
+
task :clone do
|
11
|
+
on roles :all do
|
12
|
+
if test " [ -d #{repo_path}/.hg ] "
|
13
|
+
info t(:mirror_exists, at: repo_path)
|
14
|
+
else
|
15
|
+
within deploy_path do
|
16
|
+
execute "hg", "clone", "--noupdate", repo_url, repo_path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Pull changes from the remote repo'
|
23
|
+
task :update => :'hg:clone' do
|
24
|
+
on roles :all do
|
25
|
+
within repo_path do
|
26
|
+
execute "hg", "pull"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Copy repo to releases'
|
32
|
+
task :create_release => :'hg:update' do
|
33
|
+
on roles :all do
|
34
|
+
within repo_path do
|
35
|
+
execute "hg", "archive", release_path, "--rev", fetch(:branch)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|