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.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +89 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +674 -0
  7. data/README.md +226 -0
  8. data/Rakefile +5 -0
  9. data/bin/cap +2 -3
  10. data/bin/capify +7 -77
  11. data/capistrano-public_cert.pem +22 -0
  12. data/capistrano.gemspec +35 -0
  13. data/features/deploy.feature +52 -0
  14. data/features/installation.feature +16 -0
  15. data/features/remote_file_task.feature +14 -0
  16. data/features/step_definitions/assertions.rb +90 -0
  17. data/features/step_definitions/cap_commands.rb +8 -0
  18. data/features/step_definitions/setup.rb +25 -0
  19. data/features/support/env.rb +12 -0
  20. data/features/support/remote_command_helpers.rb +20 -0
  21. data/lib/Capfile +3 -0
  22. data/lib/capistrano/all.rb +16 -0
  23. data/lib/capistrano/application.rb +60 -0
  24. data/lib/capistrano/configuration/question.rb +42 -0
  25. data/lib/capistrano/configuration/server.rb +133 -0
  26. data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
  27. data/lib/capistrano/configuration/servers.rb +53 -58
  28. data/lib/capistrano/configuration.rb +84 -30
  29. data/lib/capistrano/console.rb +1 -0
  30. data/lib/capistrano/defaults.rb +13 -0
  31. data/lib/capistrano/deploy.rb +3 -0
  32. data/lib/capistrano/dotfile.rb +3 -0
  33. data/lib/capistrano/dsl/env.rb +64 -0
  34. data/lib/capistrano/dsl/paths.rb +94 -0
  35. data/lib/capistrano/dsl/stages.rb +15 -0
  36. data/lib/capistrano/dsl/task_enhancements.rb +53 -0
  37. data/lib/capistrano/dsl.rb +48 -0
  38. data/lib/capistrano/git.rb +1 -0
  39. data/lib/capistrano/hg.rb +1 -0
  40. data/lib/capistrano/i18n.rb +34 -0
  41. data/lib/capistrano/install.rb +1 -0
  42. data/lib/capistrano/setup.rb +21 -0
  43. data/lib/capistrano/tasks/console.rake +21 -0
  44. data/lib/capistrano/tasks/deploy.rake +204 -0
  45. data/lib/capistrano/tasks/framework.rake +67 -0
  46. data/lib/capistrano/tasks/git.rake +62 -0
  47. data/lib/capistrano/tasks/hg.rake +39 -0
  48. data/lib/capistrano/tasks/install.rake +39 -0
  49. data/lib/capistrano/templates/Capfile +26 -0
  50. data/lib/capistrano/templates/deploy.rb.erb +40 -0
  51. data/lib/capistrano/templates/stage.rb.erb +42 -0
  52. data/lib/capistrano/version.rb +1 -20
  53. data/lib/capistrano/version_validator.rb +37 -0
  54. data/lib/capistrano.rb +0 -2
  55. data/spec/integration/dsl_spec.rb +344 -0
  56. data/spec/integration_spec_helper.rb +7 -0
  57. data/spec/lib/capistrano/application_spec.rb +61 -0
  58. data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
  59. data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
  60. data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
  61. data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
  62. data/spec/lib/capistrano/configuration_spec.rb +101 -0
  63. data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
  64. data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
  65. data/spec/lib/capistrano/dsl_spec.rb +63 -0
  66. data/spec/lib/capistrano/version_validator_spec.rb +103 -0
  67. data/spec/lib/capistrano_spec.rb +8 -0
  68. data/spec/spec_helper.rb +15 -0
  69. data/spec/support/.gitignore +1 -0
  70. data/spec/support/Vagrantfile +13 -0
  71. data/spec/support/matchers.rb +5 -0
  72. data/spec/support/tasks/database.cap +11 -0
  73. data/spec/support/test_app.rb +138 -0
  74. metadata +251 -179
  75. data/CHANGELOG +0 -512
  76. data/MIT-LICENSE +0 -20
  77. data/README +0 -43
  78. data/examples/sample.rb +0 -14
  79. data/lib/capistrano/callback.rb +0 -45
  80. data/lib/capistrano/cli/execute.rb +0 -82
  81. data/lib/capistrano/cli/help.rb +0 -102
  82. data/lib/capistrano/cli/help.txt +0 -53
  83. data/lib/capistrano/cli/options.rb +0 -183
  84. data/lib/capistrano/cli/ui.rb +0 -28
  85. data/lib/capistrano/cli.rb +0 -47
  86. data/lib/capistrano/command.rb +0 -161
  87. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
  88. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  89. data/lib/capistrano/configuration/actions/invocation.rb +0 -134
  90. data/lib/capistrano/configuration/callbacks.rb +0 -148
  91. data/lib/capistrano/configuration/connections.rb +0 -159
  92. data/lib/capistrano/configuration/execution.rb +0 -126
  93. data/lib/capistrano/configuration/loading.rb +0 -198
  94. data/lib/capistrano/configuration/namespaces.rb +0 -196
  95. data/lib/capistrano/configuration/roles.rb +0 -51
  96. data/lib/capistrano/configuration/variables.rb +0 -127
  97. data/lib/capistrano/errors.rb +0 -15
  98. data/lib/capistrano/extensions.rb +0 -57
  99. data/lib/capistrano/gateway.rb +0 -131
  100. data/lib/capistrano/logger.rb +0 -59
  101. data/lib/capistrano/recipes/compat.rb +0 -32
  102. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  103. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
  104. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
  105. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  106. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
  107. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  108. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
  109. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
  110. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
  111. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
  112. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
  113. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
  114. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  115. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
  116. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  117. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
  118. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  119. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  120. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
  121. data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
  122. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  123. data/lib/capistrano/recipes/deploy.rb +0 -494
  124. data/lib/capistrano/recipes/standard.rb +0 -37
  125. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  126. data/lib/capistrano/recipes/upgrade.rb +0 -33
  127. data/lib/capistrano/server_definition.rb +0 -51
  128. data/lib/capistrano/shell.rb +0 -256
  129. data/lib/capistrano/ssh.rb +0 -109
  130. data/lib/capistrano/task_definition.rb +0 -69
  131. data/lib/capistrano/upload.rb +0 -146
  132. data/test/cli/execute_test.rb +0 -132
  133. data/test/cli/help_test.rb +0 -139
  134. data/test/cli/options_test.rb +0 -226
  135. data/test/cli/ui_test.rb +0 -28
  136. data/test/cli_test.rb +0 -17
  137. data/test/command_test.rb +0 -309
  138. data/test/configuration/actions/file_transfer_test.rb +0 -40
  139. data/test/configuration/actions/inspect_test.rb +0 -62
  140. data/test/configuration/actions/invocation_test.rb +0 -202
  141. data/test/configuration/callbacks_test.rb +0 -206
  142. data/test/configuration/connections_test.rb +0 -288
  143. data/test/configuration/execution_test.rb +0 -159
  144. data/test/configuration/loading_test.rb +0 -127
  145. data/test/configuration/namespace_dsl_test.rb +0 -297
  146. data/test/configuration/roles_test.rb +0 -47
  147. data/test/configuration/servers_test.rb +0 -90
  148. data/test/configuration/variables_test.rb +0 -180
  149. data/test/configuration_test.rb +0 -81
  150. data/test/deploy/scm/accurev_test.rb +0 -23
  151. data/test/deploy/scm/base_test.rb +0 -55
  152. data/test/deploy/scm/git_test.rb +0 -112
  153. data/test/deploy/strategy/copy_test.rb +0 -147
  154. data/test/extensions_test.rb +0 -69
  155. data/test/fixtures/cli_integration.rb +0 -5
  156. data/test/fixtures/config.rb +0 -5
  157. data/test/fixtures/custom.rb +0 -3
  158. data/test/gateway_test.rb +0 -167
  159. data/test/logger_test.rb +0 -123
  160. data/test/server_definition_test.rb +0 -108
  161. data/test/shell_test.rb +0 -64
  162. data/test/ssh_test.rb +0 -97
  163. data/test/task_definition_test.rb +0 -101
  164. data/test/upload_test.rb +0 -131
  165. data/test/utils.rb +0 -42
  166. 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,15 @@
1
+ module Capistrano
2
+ module DSL
3
+ module Stages
4
+
5
+ def stages
6
+ Dir['config/deploy/*.rb'].map { |f| File.basename(f, '.rb') }
7
+ end
8
+
9
+ def stage_set?
10
+ !!fetch(:stage, false)
11
+ end
12
+
13
+ end
14
+ end
15
+ 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