new_artrails_capistrano 0.0.1

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.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in new_artrails_capistrano.gemspec
6
+ gemspec
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A sample Guardfile
4
+ # More info at https://github.com/guard/guard#readme
5
+
6
+ ## Uncomment and set this to only include directories you want to watch
7
+ # directories %w(app lib config test spec features) \
8
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
9
+
10
+ ## Note: if you are using the `directories` clause above and you are not
11
+ ## watching the project directory ('.'), then you will want to move
12
+ ## the Guardfile to a watched dir and symlink it back, e.g.
13
+ #
14
+ # $ mkdir config
15
+ # $ mv Guardfile config/
16
+ # $ ln -s config/Guardfile .
17
+ #
18
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
19
+
20
+ # USE PRIVATE GLOBAL CONFIG TO CUSTOMIZE:
21
+ # ~/.guard.rb
22
+ # notification :growl # on OSX with growl notifications installed
23
+ # clearing :on # clears terminal
24
+ #
25
+
26
+ guard 'reek' do
27
+ watch(/.+\.rb$/)
28
+ watch('.reek')
29
+ end
30
+
31
+ # Note: The cmd option is now required due to the increasing number of ways
32
+ # rspec may be run, below are examples of the most common uses.
33
+ # * bundler: 'bundle exec rspec'
34
+ # * bundler binstubs: 'bin/rspec'
35
+ # * spring: 'bin/rspec' (This will use spring if running and you have
36
+ # installed the spring binstubs per the docs)
37
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
38
+ # * 'just' rspec: 'rspec'
39
+
40
+ guard :rspec, cmd: 'bundle exec rspec' do
41
+ require 'guard/rspec/dsl'
42
+ dsl = Guard::RSpec::Dsl.new(self)
43
+
44
+ # Feel free to open issues for suggestions and improvements
45
+
46
+ # RSpec files
47
+ rspec = dsl.rspec
48
+ watch(rspec.spec_helper) { rspec.spec_dir }
49
+ watch(rspec.spec_support) { rspec.spec_dir }
50
+ watch(rspec.spec_files)
51
+
52
+ # Ruby files
53
+ ruby = dsl.ruby
54
+ dsl.watch_spec_files_for(ruby.lib_files)
55
+
56
+ # Rails files
57
+ rails = dsl.rails(view_extensions: %w[erb haml slim])
58
+ dsl.watch_spec_files_for(rails.app_files)
59
+ dsl.watch_spec_files_for(rails.views)
60
+
61
+ watch(rails.controllers) do |m|
62
+ [
63
+ rspec.spec.call("routing/#{m[1]}_routing"),
64
+ rspec.spec.call("controllers/#{m[1]}_controller"),
65
+ rspec.spec.call("acceptance/#{m[1]}")
66
+ ]
67
+ end
68
+
69
+ # Rails config changes
70
+ watch(rails.spec_helper) { rspec.spec_dir }
71
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
72
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
73
+
74
+ # Capybara features specs
75
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
76
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
77
+
78
+ # Turnip features and steps
79
+ watch(%r{^spec/acceptance/(.+)\.feature$})
80
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
81
+ Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance'
82
+ end
83
+ end
84
+
85
+ # guard :rubocop do
86
+ # watch(/.+\.rb$/)
87
+ # watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
88
+ # watch(%r{(?:.+/)?\.rubocop_todo\.yml$}) { |m| File.dirname(m[0]) }
89
+ # end
90
+ # split the development into parts (e.g. frontend and backend)
91
+ # guard -g <group>
92
+ scope group: :specs
93
+
94
+ group 'specs', halt_on_fail: false do
95
+ guard :bundler do
96
+ require 'guard/bundler'
97
+ require 'guard/bundler/verify'
98
+ helper = Guard::Bundler::Verify.new
99
+
100
+ files = ['Gemfile']
101
+ files += Dir['*.gemspec'] if files.any? { |f| helper.uses_gemspec?(f) }
102
+
103
+ # Assume files are symlinked from somewhere
104
+ files.each { |file| watch(helper.real_path(file)) }
105
+ end
106
+
107
+ # cmd: show less output, but still provide enough info on a failed test
108
+ guard :rspec, all_on_start: true, cmd: 'rspec -c -fp' do
109
+ watch(%r{^spec/.+_spec\.rb$})
110
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
111
+ watch('spec/spec_helper.rb') { 'spec/lib' }
112
+ end
113
+
114
+ guard :rubocop, all_on_start: true, cmd: 'rubocop --format fuubar -F -D' do
115
+ watch(%r{^spec/.+_spec\.rb$})
116
+ watch(%r{^lib/(.+)\.rb$})
117
+ end
118
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Efigence S.A.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ .codeclimate.yml
2
+ .gitignore
3
+ .rspec_status
4
+ .rubocop.yml
5
+ .rubocop_todo.yml
6
+ .travis.yml
7
+ CHANGELOG.md
8
+ CODE_OF_CONDUCT.md
9
+ Gemfile
10
+ Guardfile
11
+ LICENSE.txt
12
+ Manifest.txt
13
+ README.md
14
+ Rakefile
15
+ bin/console
16
+ bin/setup
17
+ config.reek
18
+ lib/.keep
19
+ lib/capistrano/new_artrails_capistrano.rb
20
+ lib/capistrano/new_artrails_capistrano/version.rb
21
+ lib/capistrano/tasks/new_artrails_capistrano.rake
22
+ lib/new_artrails_capistrano.rb
23
+ new_artrails_capistrano.gemspec
24
+ rubocop_output.json
25
+ spec/lib/.keep
26
+ spec/lib/capistrano/new_artrails_capistrano_spec.rb
27
+ spec/new_artrails_capistrano_spec.rb
28
+ spec/spec_helper.rb
@@ -0,0 +1,54 @@
1
+ # Capistrano [![Gem Version](https://badge.fury.io/rb/new_artrails_capistrano.svg)](https://badge.fury.io/rb/new_artrails_capistrano) [![Build Status](https://travis-ci.org/efigence/new_artrails_capistrano.svg?branch=master)](https://travis-ci.org/efigence/new_artrails_capistrano) [![Coverage Status](https://coveralls.io/repos/github/efigence/new_artrails_capistrano/badge.svg?branch=master)](https://coveralls.io/github/efigence/new_artrails_capistrano?branch=master) [![Code Climate](https://codeclimate.com/github/efigence/new_artrails_capistrano/badges/gpa.svg)](https://codeclimate.com/github/efigence/new_artrails_capistrano)
2
+
3
+ Capistrano 3 deployment using Rsync, a local Git repository and sudo as user.
4
+
5
+ This gem is a viable alternative to Git deployments on production machines. Commands can be run under a different user than the `deploy` user.
6
+
7
+ ## Dependencies
8
+
9
+ * None
10
+
11
+ ## Installation
12
+
13
+ ```
14
+ $ echo '2.1.1' > .ruby-version
15
+ $ rvm use
16
+ ```
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem 'new_artrails_capistrano'
22
+ ```
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install new_artrails_capistrano
31
+
32
+ ## Usage
33
+
34
+ ```
35
+ ```
36
+
37
+ ## Development
38
+
39
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
40
+
41
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
+
43
+ ```
44
+ $ guard # require './lib/new_artrails_capistrano'
45
+ ```
46
+
47
+ ## Contributing
48
+
49
+ Bug reports and pull requests are welcome on GitHub at https://github.com/efigence/new_artrails_capistrano. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
50
+
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ RuboCop::RakeTask.new(:rubocop) do |task|
10
+ task.requires << 'rubocop-rspec'
11
+ task.formatters = ['json']
12
+ task.options = ['--display-cop-names', '-orubocop_output.json']
13
+ end
14
+
15
+ task default: :spec
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'new_artrails_capistrano'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1 @@
1
+ # https://github.com/troessner/reek/blob/master/defaults.reek
File without changes
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ load File.expand_path('../tasks/new_artrails_capistrano.rake', __FILE__)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module NewArtrailsCapistrano
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
@@ -0,0 +1,742 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+ require 'capistrano/all'
5
+ # require 'capistrano/setup'
6
+ require 'capistrano/deploy'
7
+ include Capistrano::DSL
8
+ # require 'capistrano/rails'
9
+ # require 'capistrano/bundler'
10
+ require 'capistrano/rails/assets'
11
+ # require 'capistrano/rails/migrations'
12
+ require "capistrano/scm/git"
13
+ install_plugin Capistrano::SCM::Git
14
+ require 'capistrano/new_artrails_capistrano/helpers'
15
+ require 'capistrano/new_artrails_capistrano/front_helpers'
16
+
17
+ include Capistrano::NewArtrailsCapistrano::Helpers
18
+ include Capistrano::NewArtrailsCapistrano::FrontHelpers
19
+
20
+ remote_cache = lambda do
21
+ cache = fetch(:remote_cache) || 'shared/cached-copy-deploy'
22
+ cache = deploy_to + '/' + cache if cache && cache !~ /^\//
23
+ cache
24
+ end
25
+
26
+ namespace :load do
27
+ task :defaults do
28
+ set :new_artrails_capistrano_sudo_as, -> { new_artrails_capistrano_sudo_as }
29
+ # rsync
30
+ if RUBY_PLATFORM =~ /mswin|mingw/
31
+ set :rsync_options, '-az --delete --exclude=\'.git*\' --exclude=\'.rvmrc\' --exclude=\'vendor/bundle\' --exclude=\'doc\' --delete-excluded -e "ssh -i C:\\keys\\openssh-private-key.pub"'
32
+ else # linux, mac
33
+ set :rsync_exclude, %w[.git* .rvmrc* vendor/bundle doc]
34
+ set :rsync_options, %w[-az --delete --delete-excluded]
35
+ end
36
+ set :rsync_include, %w[]
37
+
38
+ set :local_cache, -> { "/tmp/.#{fetch(:application)}_rsync_cache" }
39
+
40
+ set :repo_url, File.expand_path('.')
41
+
42
+ # :auto (default): just tries to find the correct path. ~/.rvm wins over /usr/local/rvm
43
+ # :system: defines the RVM path to /usr/local/rvm
44
+ # :user: defines the RVM path to ~/.rvm
45
+ # deploy.rb or stage file (staging.rb, production.rb or else)
46
+ set :rvm_type, :system # Defaults to: :auto
47
+ set :rvm_ruby_version, :default # Defaults to: 'default'
48
+ # set :rvm_custom_path, '~/.myveryownrvm' # only needed if not detected
49
+
50
+ set :new_artrails_capistrano_log_dir_name, -> { File.basename(fetch(:deploy_to) || fetch(:application)) }
51
+
52
+ set :ssh_options, {
53
+ keys: %w(/home/#{user}/.ssh/id_rsa),
54
+ auth_methods: %w(publickey password)
55
+ }
56
+
57
+ set :asset_env, "RAILS_GROUPS=assets"
58
+ set :assets_prefix, "assets"
59
+
60
+ set :use_sudo, false
61
+
62
+ set :remote_cache, -> { "shared/cached-copy-#{fetch(:local_user) || 'deploy'}" }
63
+
64
+ # no proxy for localhost
65
+ set :proxy_host, nil # e.g. 'proxy.non.3dart.com'
66
+ set :proxy_port, nil # e.g. '3128'
67
+
68
+ set :app_address, nil
69
+
70
+ set :skip_deploy_tagging, true
71
+ end
72
+ end
73
+
74
+ namespace :artrails do
75
+ task :set_current_revision do
76
+ on roles :app, exclude: :no_release do |task|
77
+ run_locally do
78
+ File.open(File.join(backend_local_cache, 'REVISION'), 'w') { |f| f.puts(backend_revision) }
79
+ File.open(File.join(backend_local_cache, 'BRANCH'), 'w+') { |f| f.puts(backend_branch) }
80
+
81
+ # FIXME:
82
+ # find_servers(:roles => :app, :except => { :no_release => true }).each do |server|
83
+ server = host
84
+
85
+ system("mkdir -p #{backend_local_cache}")
86
+ system("cp #{backend_local_cache}/REVISION #{backend_local_cache}/")
87
+ system("cp #{backend_local_cache}/BRANCH #{backend_local_cache}/")
88
+ end
89
+ end
90
+ end
91
+ task :update_versions_html do
92
+ on roles :app, exclude: :no_release do |task|
93
+ versions_file = "#{shared_path}/versions.html"
94
+ revision_log_message_cleaned = %Q{#{revision_log_message}}
95
+ cmd = <<-CMD
96
+ sudo -iu #{new_artrails_capistrano_sudo_as} touch #{versions_file} &&
97
+ sudo -iu #{new_artrails_capistrano_sudo_as} chmod g+w #{versions_file} &&
98
+ sudo -iu #{new_artrails_capistrano_sudo_as} chgrp mongrel #{versions_file} &&
99
+ echo "#{revision_log_message_cleaned}<br />"|cat - #{versions_file} > /tmp/#{fetch(:application)}_#{fetch(:stage)}_versions.html &&
100
+ chmod g+rw /tmp/#{fetch(:application)}_#{fetch(:stage)}_versions.html &&
101
+ chmod g+rw /tmp/#{fetch(:application)}_#{fetch(:stage)}_versions.html &&
102
+ sudo -iu #{new_artrails_capistrano_sudo_as} cp /tmp/#{fetch(:application)}_#{fetch(:stage)}_versions.html #{versions_file} &&
103
+ sudo -iu #{new_artrails_capistrano_sudo_as} ln -fs #{versions_file} #{release_path}/public/versions.html
104
+ CMD
105
+ new_artrails_capistrano_run cmd.gsub(/\r?\n/, '').gsub(/\s+/, ' ')
106
+ end
107
+ end
108
+ desc <<-DESC
109
+ set symlinks for configs logs, set rights and check is it working
110
+ DESC
111
+ namespace :symlink do
112
+ task :config do
113
+ on roles :app, exclude: :no_release do |task|
114
+ # FIXME:
115
+ # servers = find_servers_for_task(current_task)
116
+ # servers.each do |server|
117
+ server = host
118
+ fetch(:new_artrails_capistrano_config_files).each do |cf|
119
+ new_artrails_capistrano_run "ln -fs #{shared_path}/config/#{cf} #{release_path}/config/#{cf}"
120
+ end
121
+ end
122
+ end
123
+
124
+ task :log do
125
+ on roles :app, exclude: :no_release do
126
+ new_artrails_capistrano_run "rm -rf #{release_path}/log"
127
+ new_artrails_capistrano_run "ln -s /var/log/#{fetch(:new_artrails_capistrano_sudo_as)}/#{fetch(:new_artrails_capistrano_log_dir_name)}/ #{release_path}/log"
128
+ end
129
+ end
130
+ end
131
+
132
+ task :check_is_it_working do
133
+ on roles :app, exclude: :no_release do
134
+ puts "Sleeping 5 seconds..."
135
+ sleep( 5 )
136
+ puts "Asking is it working..."
137
+ if fetch(:app_address).to_s[/8080/]
138
+ proxy_host = nil
139
+ proxy_port = nil
140
+ else
141
+ proxy_host = fetch(:proxy_host)
142
+ proxy_port = fetch(:proxy_port)
143
+ end
144
+ http = Net::HTTP::Proxy(proxy_host, proxy_port).start(*fetch(:app_address).split(':'))
145
+ path='/isItWorking'
146
+ resp, data = http.get(path)
147
+ puts "#{resp.code} #{resp.message} : #{data}"
148
+ end
149
+ end
150
+
151
+ task :tailf do
152
+ log_file = "#{current_path}/log/production.log"
153
+ new_artrails_capistrano_run "tail -f #{log_file}" do |channel, stream, data|
154
+ puts data if stream == :out
155
+ if stream == :err
156
+ puts "[Error: #{channel[:host]}] #{data}"
157
+ break
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ namespace :maintenance do
164
+ desc "Maintenance start"
165
+ task :on do
166
+ on roles :web do
167
+ if test "[ -f #{release_path}/config/maintenance.yml ]"
168
+ new_artrails_capistrano_run "cp #{release_path}/config/maintenance.yml #{release_path}/tmp/maintenance.yml"
169
+ end
170
+ end
171
+ end
172
+
173
+ desc "Maintenance stop"
174
+ task :off do
175
+ on roles :web do
176
+ new_artrails_capistrano_run "rm -rf #{release_path}/tmp/maintenance.yml"
177
+ end
178
+ end
179
+ end
180
+
181
+ namespace :deploy do
182
+ desc "Tag deployed release"
183
+ task :tag do
184
+ run_locally do
185
+ if ENV['SKIP_DEPLOY_TAGGING'] || fetch(:skip_deploy_tagging, false)
186
+ info "Skipped deploy tagging"
187
+ else
188
+ tag_name = "#{fetch(:deploy_tag, "deployed")}_#{fetch(:stage)}"
189
+ latest_revision = fetch(:current_revision)
190
+ unless fetch(:sshkit_backend) == SSHKit::Backend::Printer # unless --dry-run flag present
191
+ execute :git, "tag -f #{tag_name} #{latest_revision}"
192
+ execute :git, "push -f --tags"
193
+ end
194
+ info "Tagged #{latest_revision} with #{tag_name}"
195
+ end
196
+ end
197
+ end
198
+
199
+ task :front do
200
+ on roles :app, exclude: :no_release do
201
+ puts '[FRONT] updating local cache'
202
+ system(front_command)
203
+
204
+ File.open(File.join(front_local_cache, "REVISION"), "w") { |f| f.puts(backend_revision) }
205
+ File.open(File.join(front_local_cache, "BRANCH"), "w") { |f| f.puts(backend_branch) }
206
+
207
+ File.open(File.join(front_local_cache, 'FRONT_REVISION'), 'w') { |f| f.puts(front_revision) }
208
+ File.open(File.join(front_local_cache, 'FRONT_BRANCH'), 'w+') { |f| f.puts(front_branch) }
209
+
210
+ # FIXME:
211
+ # find_servers(:roles => :app, :except => { :no_release => true }).each do |server|
212
+ server = host
213
+
214
+ system("mkdir -p #{front_local_cache}/#{front_dist_dir_name}")
215
+
216
+ system("cp #{front_local_cache}/REVISION #{front_local_cache}/#{front_dist_dir_name}/")
217
+ system("cp #{front_local_cache}/BRANCH #{front_local_cache}/#{front_dist_dir_name}/")
218
+
219
+ system("cp #{front_local_cache}/FRONT_REVISION #{front_local_cache}/#{front_dist_dir_name}/")
220
+ system("cp #{front_local_cache}/FRONT_BRANCH #{front_local_cache}/#{front_dist_dir_name}/")
221
+
222
+ release_roles(:all).each do |role|
223
+ user = role.user || fetch(:user)
224
+ user = user + "@" unless user.nil?
225
+
226
+ rsync_args = []
227
+ rsync_args.concat front_rsync_options
228
+ rsync_args.concat (front_rsync_include || []).map{|e| "--include #{e}"}
229
+ rsync_args.concat (front_rsync_exclude || []).map{|e| "--exclude #{e}"}
230
+ rsync_args << front_local_cache + "/#{front_dist_dir_name}/"
231
+ rsync_args << "#{user}#{role.hostname}:#{front_remote_cache.call}"
232
+
233
+ run_locally do
234
+ execute :rsync, *rsync_args
235
+ end
236
+
237
+ new_artrails_capistrano_run( "chmod +r+w+x -R #{front_remote_cache.call}" )
238
+ new_artrails_capistrano_run( "chmod g+w -R #{front_remote_cache.call}" )
239
+ new_artrails_capistrano_run( "chgrp -R mongrel #{front_remote_cache.call}" )
240
+
241
+ copy = %(#{front_copy_command} "#{front_remote_cache.call}/" "#{front_release_path}/")
242
+ on release_roles(:all) do
243
+ puts copy
244
+ new_artrails_capistrano_run copy
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ Rake::Task["deploy:set_current_revision"].clear_actions
251
+ desc "Place a REVISION file with the current revision SHA in the current release path and a BRANCH file with name"
252
+ task :set_current_revision do
253
+ on release_roles(:all) do
254
+ # NOTE: cannot use this with :front deployment
255
+ # # NOTE: echo called twice on purpose, because only that way it works...
256
+ # cmd =<<-CMD
257
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} bash -c "
258
+ # echo '#{fetch(:current_revision)}' > #{release_path}/REVISION &&
259
+ # echo -e '#{fetch(:current_revision)}' > #{release_path}/REVISION &&
260
+ # chmod g+w -R #{release_path}/REVISION &&
261
+ # chgrp #{fetch(:new_artrails_capistrano_sudo_as)} #{release_path}/REVISION
262
+ # "
263
+ # CMD
264
+ # new_artrails_capistrano_run cmd.gsub(/\r?\n/, '').gsub(/\s+/, ' ')
265
+ # # NOTE: echo called twice on purpose, because only that way it works...
266
+ # cmd =<<-CMD
267
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} bash -c "
268
+ # echo '#{fetch(:branch)}' > #{release_path}/BRANCH &&
269
+ # echo -e '#{fetch(:branch)}' > #{release_path}/BRANCH &&
270
+ # chmod g+w -R #{release_path}/BRANCH &&
271
+ # chgrp #{fetch(:new_artrails_capistrano_sudo_as)} #{release_path}/BRANCH
272
+ # "
273
+ # CMD
274
+ # new_artrails_capistrano_run cmd.gsub(/\r?\n/, '').gsub(/\s+/, ' ')
275
+ end
276
+ end
277
+
278
+ Rake::Task["deploy:cleanup"].clear_actions
279
+ desc "Clean up old releases"
280
+ task :cleanup do
281
+ on release_roles :all do |host|
282
+ releases = capture(:ls, "-x", releases_path).split
283
+ if !(releases.all? { |e| /^\d{14}$/ =~ e })
284
+ warn t(:skip_cleanup, host: host.to_s)
285
+ elsif releases.count >= fetch(:keep_releases)
286
+ info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: releases.count)
287
+ directories = (releases - releases.last(fetch(:keep_releases)))
288
+ if directories.any?
289
+ directories_str = directories.map do |release|
290
+ releases_path.join(release)
291
+ end.join(" ")
292
+ new_artrails_capistrano_run "rm -rf #{directories_str}" if directories_str.to_s[/\/releases\//]
293
+ else
294
+ info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
295
+ end
296
+ end
297
+ end
298
+ end
299
+
300
+ Rake::Task["deploy:log_revision"].clear_actions
301
+ desc "Log details of the deploy"
302
+ task :log_revision do
303
+ on release_roles(:all) do
304
+ within releases_path do
305
+ execute :echo, %Q{"#{revision_log_message}" >> #{revision_log}}
306
+ execute :chmod, "g+w #{revision_log}"
307
+ end
308
+ end
309
+ end
310
+
311
+ namespace :bundler do
312
+ task :install do
313
+ on fetch(:bundle_servers) do
314
+ within release_path do
315
+ with fetch(:bundle_env_variables, {}) do
316
+ options = []
317
+ options << "--gemfile #{fetch(:bundle_gemfile)}" if fetch(:bundle_gemfile)
318
+ options << "--path #{fetch(:bundle_path)}" if fetch(:bundle_path)
319
+ unless test(:bundle, :check, *options)
320
+ options << "--binstubs #{fetch(:bundle_binstubs)}" if fetch(:bundle_binstubs)
321
+ options << "--jobs #{fetch(:bundle_jobs)}" if fetch(:bundle_jobs)
322
+ options << "--without #{fetch(:bundle_without)}" if fetch(:bundle_without)
323
+ options << "#{fetch(:bundle_flags)}" if fetch(:bundle_flags)
324
+ new_artrails_capistrano_run_with_rvm_in_release_path "bundle install #{options.join(' ')}"
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
330
+
331
+ desc "Remove unused gems installed by bundler"
332
+ task :clean do
333
+ on fetch(:bundle_servers) do
334
+ within release_path do
335
+ with fetch(:bundle_env_variables, {}) do
336
+ new_artrails_capistrano_run "bundle clean #{fetch(:bundle_clean_options, "")}"
337
+ end
338
+ end
339
+ end
340
+ end
341
+ end
342
+
343
+ namespace :symlink do
344
+ Rake::Task["deploy:symlink:linked_dirs"].clear_actions
345
+ desc "Symlink linked directories"
346
+ task :linked_dirs do
347
+ next unless any? :linked_dirs
348
+ on release_roles :all do
349
+ new_artrails_capistrano_run "mkdir -p #{linked_dir_parents(release_path).map(&:to_s).join(' ')}"
350
+ fetch(:linked_dirs).each do |dir|
351
+ target = release_path.join(dir)
352
+ source = shared_path.join(dir)
353
+ next if test "[ -L #{target} ]"
354
+ new_artrails_capistrano_run "rm -rf #{target.to_s}" if test "[ -d #{target.to_s} ]"
355
+ new_artrails_capistrano_run "ln -s #{source.to_s} #{target.to_s}"
356
+ end
357
+ end
358
+ end
359
+
360
+ Rake::Task["deploy:symlink:linked_files"].clear_actions
361
+ desc "Symlink linked files"
362
+ task :linked_files do
363
+ next unless any? :linked_files
364
+ on release_roles :all do
365
+ new_artrails_capistrano_run "mkdir -p #{linked_file_dirs(release_path).map(&:to_s).join(' ')}"
366
+ fetch(:linked_files).each do |file|
367
+ target = release_path.join(file)
368
+ source = shared_path.join(file)
369
+ next if test "[ -L #{target} ]"
370
+ new_artrails_capistrano_run "rm -rf #{target.to_s}" if test "[ -f #{target.to_s} ]"
371
+ new_artrails_capistrano_run "ln -s #{source.to_s} #{target.to_s}"
372
+ end
373
+ end
374
+ end
375
+ desc "Symlink release to current"
376
+ task :release do
377
+ on release_roles :all do
378
+ tmp_current_path = release_path.parent.join(current_path.basename)
379
+ new_artrails_capistrano_run "ln -s #{release_path} #{tmp_current_path}"
380
+ new_artrails_capistrano_run "mv #{tmp_current_path} #{current_path.parent}"
381
+ end
382
+ end
383
+ end
384
+ namespace :isItWorking do
385
+ task :activate do
386
+ on roles :web, exclude: :no_release do
387
+ new_artrails_capistrano_run "touch #{current_path}/tmp/isItWorking.txt"
388
+ end
389
+ end
390
+ task :deactivate do
391
+ on roles :web, exclude: :no_release do
392
+ new_artrails_capistrano_run "rm -f #{current_path}/tmp/isItWorking.txt"
393
+ end
394
+ end
395
+ end
396
+
397
+ desc 'Normalize asset timestamps'
398
+ task :normalize_assets => [:set_rails_env] do
399
+ on release_roles(fetch(:assets_roles)) do
400
+ assets = Array(fetch(:normalize_asset_timestamps, []))
401
+ if assets.any?
402
+ within release_path do
403
+ new_artrails_capistrano_run "find #{assets.join(' ')} -exec touch -t #{asset_timestamp} {} ';'; true"
404
+ end
405
+ end
406
+ end
407
+ end
408
+
409
+ desc 'Cleanup expired assets'
410
+ task :cleanup_assets => [:set_rails_env] do
411
+ next unless fetch(:keep_assets)
412
+ on release_roles(fetch(:assets_roles)) do
413
+ within release_path do
414
+ with rails_env: fetch(:rails_env) do
415
+ new_artrails_capistrano_run "rake 'assets:clean[#{fetch(:keep_assets)}]'"
416
+ end
417
+ end
418
+ end
419
+ end
420
+
421
+ desc 'Clobber assets'
422
+ task :clobber_assets => [:set_rails_env] do
423
+ on release_roles(fetch(:assets_roles)) do
424
+ within release_path do
425
+ with rails_env: fetch(:rails_env) do
426
+ new_artrails_capistrano_run "rake assets:clobber"
427
+ end
428
+ end
429
+ end
430
+ end
431
+
432
+ desc 'Rollback assets'
433
+ task :rollback_assets => [:set_rails_env] do
434
+ begin
435
+ invoke 'deploy:assets:restore_manifest'
436
+ rescue Capistrano::FileNotFound
437
+ invoke 'deploy:compile_assets'
438
+ end
439
+ end
440
+
441
+ namespace :assets do
442
+
443
+ # task :symlink do
444
+ # on roles :web, exclude: :no_release do
445
+ # cmd =<<-CMD
446
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} rm -rf #{release_path}/public/#{fetch(:assets_prefix)} &&
447
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} mkdir -p #{release_path}/public &&
448
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} mkdir -p #{shared_path}/public/#{fetch(:assets_prefix)} &&
449
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} ln -s #{shared_path}/assets #{release_path}/public/#{fetch(:assets_prefix)} &&
450
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} chmod g+w -R #{release_path}/public/#{fetch(:assets_prefix)} &&
451
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} chgrp -R #{fetch(:new_artrails_capistrano_sudo_as)} #{release_path}/public/#{fetch(:assets_prefix)} &&
452
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} chmod g+w -R #{shared_path}/public/#{fetch(:assets_prefix)} &&
453
+ # sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} chgrp -R #{fetch(:new_artrails_capistrano_sudo_as)} #{shared_path}/public/#{fetch(:assets_prefix)}
454
+ # CMD
455
+ # new_artrails_capistrano_run cmd.gsub(/\r?\n/, '').gsub(/\s+/, ' ')
456
+ # end
457
+ # end
458
+
459
+ # Rails 5 only
460
+ Rake::Task['deploy:assets:backup_manifest'].clear_actions
461
+ task :backup_manifest do
462
+ on release_roles(fetch(:assets_roles)) do
463
+ within release_path do
464
+ backup_path = release_path.join('assets_manifest_backup')
465
+ target = new_artrails_capistrano_detect_manifest_path
466
+ new_artrails_capistrano_run "mkdir -p #{backup_path}"
467
+ if test "[[ -f #{target} ]]"
468
+ new_artrails_capistrano_run "cp #{target} #{backup_path}"
469
+ else
470
+ msg = 'Rails assets manifest file not found.'
471
+ warn msg
472
+ # FIXME: Rails 5 only
473
+ # fail Capistrano::FileNotFound, msg
474
+ end
475
+ end
476
+ end
477
+ end
478
+
479
+ # Rails 5 only
480
+ Rake::Task['deploy:assets:restore_manifest'].clear_actions
481
+ task :restore_manifest do
482
+ on release_roles(fetch(:assets_roles)) do
483
+ within release_path do
484
+ target = new_artrails_capistrano_detect_manifest_path
485
+ source = release_path.join('assets_manifest_backup', File.basename(target))
486
+ if test "[[ -f #{source} && -f #{target} ]]"
487
+ new_artrails_capistrano_run "cp #{source} #{target}"
488
+ else
489
+ msg = 'Rails assets manifest file (or backup file) not found.'
490
+ warn msg
491
+ # FIXME: Rails 5 only
492
+ # fail Capistrano::FileNotFound, msg
493
+ end
494
+ end
495
+ end
496
+ end
497
+
498
+ Rake::Task['deploy:assets:precompile'].clear_actions
499
+ task :precompile do
500
+ on release_roles(fetch(:assets_roles)) do
501
+ within release_path do
502
+ with rails_env: fetch(:rails_env), rails_groups: fetch(:rails_assets_groups) do
503
+ # execute :rake, "assets:precompile"
504
+ # require 'byebug'
505
+ # byebug
506
+ cmd =<<-CMD
507
+ sudo -iu #{fetch(:new_artrails_capistrano_sudo_as)} sh -c "
508
+ source\\\\ '/usr/local/rvm/scripts/rvm' &&
509
+ cd #{release_path} &&
510
+ RAILS_ENV=#{fetch(:rails_env)} #{fetch(:asset_env)} bundle exec rake assets:precompile &&
511
+ chmod g+w -R #{shared_path}/public/#{fetch(:assets_prefix)} &&
512
+ chgrp -R #{fetch(:new_artrails_capistrano_sudo_as)} #{shared_path}/public/#{fetch(:assets_prefix)}
513
+ "
514
+ CMD
515
+ new_artrails_capistrano_run cmd.gsub(/\r?\n/, '').gsub(/\s+/, ' ')
516
+ end
517
+ end
518
+ end
519
+ end
520
+ end
521
+
522
+ namespace :web_server do
523
+ task :start do
524
+ on roles :app do
525
+ new_artrails_capistrano_run "nohup #{current_path}/script/production start"
526
+ end
527
+ end
528
+
529
+ task :stop do
530
+ on roles :app do
531
+ new_artrails_capistrano_run "nohup #{current_path}/script/production stop"
532
+ end
533
+ end
534
+
535
+ task :restart do
536
+ on roles :app, exclude: :no_release do
537
+ new_artrails_capistrano_run "nohup #{current_path}/script/production restart"
538
+ end
539
+ end
540
+ end
541
+
542
+ # custom task
543
+ task :setup do # |task|
544
+ on roles :app, exclude: :no_release do
545
+ dirs = [deploy_to, releases_path, shared_path]
546
+ dirs += fetch(:linked_dirs).map { |d| File.join(shared_path, d) }
547
+ new_artrails_capistrano_run "mkdir -p #{dirs.join(' ')}"
548
+ # FIXME:
549
+ # servers = find_servers_for_task(current_task)
550
+ # servers.each do |server|
551
+ server = host
552
+ fetch(:new_artrails_capistrano_config_files).each do |cf|
553
+ new_artrails_capistrano_run("mkdir -p #{shared_path}/config")
554
+ if file_exists?("#{shared_path}/config/#{cf}")
555
+ puts "Skip. File exists: #{shared_path}/config/#{cf}"
556
+ else
557
+ new_artrails_capistrano_run("touch #{shared_path}/config/#{cf}")
558
+ new_artrails_capistrano_run("chmod g+rw #{shared_path}/config/#{cf}")
559
+ cf_path = "#{local_user}@#{server}:#{shared_path}/config/#{cf}"
560
+ puts "scp config/#{cf} #{cf_path}"
561
+ system("scp config/#{cf} #{cf_path}")
562
+ end
563
+ end
564
+ # FIXME:
565
+ # servers = find_servers_for_task(current_task)
566
+ # servers.each do |server|
567
+
568
+ # obsolete
569
+ # new_artrails_capistrano_run("mkdir -p #{shared_path}/pids")
570
+
571
+ if revision_log.to_s[/\.log\z/]
572
+ new_artrails_capistrano_run "pwd && rm -rf #{revision_log}" # don't reject command below
573
+ end
574
+ if rsync_remote_cache.to_s[/cached\-copy\-/]
575
+ new_artrails_capistrano_run "pwd && rm -rf #{deploy_to}/#{rsync_remote_cache}" # don't reject command below
576
+ end
577
+ if front_rsync_remote_cache.to_s[/cached\-copy\-/]
578
+ new_artrails_capistrano_run "pwd && rm -rf #{deploy_to}/#{front_rsync_remote_cache}" # don't reject command below
579
+ end
580
+ new_artrails_capistrano_run "sudo -u #{fetch(:new_artrails_capistrano_sudo_as)} chmod -R g+rw #{deploy_to}"
581
+ new_artrails_capistrano_run "sudo -u #{fetch(:new_artrails_capistrano_sudo_as)} chgrp -R #{fetch(:new_artrails_capistrano_sudo_as)} #{deploy_to}"
582
+
583
+ unless file_exists?("#{deploy_to}/#{rsync_remote_cache}")
584
+ new_artrails_capistrano_run "sudo -u #{fetch(:new_artrails_capistrano_sudo_as)} chmod g+w -R #{shared_path}"
585
+ new_artrails_capistrano_run "pwd && mkdir -p #{deploy_to}/#{rsync_remote_cache}"
586
+ new_artrails_capistrano_run "chgrp -R #{fetch(:new_artrails_capistrano_sudo_as)} #{deploy_to}/#{rsync_remote_cache}"
587
+ new_artrails_capistrano_run "chmod g+w #{deploy_to}/#{rsync_remote_cache}"
588
+ end
589
+
590
+ # prepare custom log dir for symlink
591
+ new_artrails_capistrano_run "mkdir -p /var/log/#{fetch(:new_artrails_capistrano_sudo_as)}/#{fetch(:new_artrails_capistrano_log_dir_name)}"
592
+ end
593
+ end
594
+
595
+ namespace :git do
596
+ desc "Upload the git wrapper script, this script guarantees that we can script git without getting an interactive prompt"
597
+ task :wrapper do
598
+ on release_roles :all do
599
+ puts "Doing nothing"
600
+ # execute :mkdir, "-p", File.dirname(fetch(:git_wrapper_path)).shellescape
601
+ # upload! StringIO.new("#!/bin/sh -e\nexec /usr/bin/ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no \"$@\"\n"), fetch(:git_wrapper_path)
602
+ # execute :chmod, "700", fetch(:git_wrapper_path).shellescape
603
+ end
604
+ end
605
+
606
+ desc "Check that the repository is reachable"
607
+ task check: :'git:wrapper' do
608
+ fetch(:branch)
609
+ on release_roles :all do
610
+ puts "Doing nothing"
611
+ # with fetch(:git_environmental_variables) do
612
+ # git_plugin.check_repo_is_reachable
613
+ # end
614
+ end
615
+ end
616
+
617
+ desc "Clone the repo to the cache"
618
+ task clone: :'git:wrapper' do
619
+ on release_roles :all do
620
+ puts "Doing nothing"
621
+ # if git_plugin.repo_mirror_exists?
622
+ # info t(:mirror_exists, at: repo_path)
623
+ # else
624
+ # within deploy_path do
625
+ # with fetch(:git_environmental_variables) do
626
+ # git_plugin.clone_repo
627
+ # end
628
+ # end
629
+ # end
630
+ end
631
+ end
632
+
633
+ desc "Update the repo mirror to reflect the origin state"
634
+ task update: :'git:clone' do
635
+ on release_roles :all do
636
+ puts "Doing nothing"
637
+ # within repo_path do
638
+ # with fetch(:git_environmental_variables) do
639
+ # git_plugin.update_mirror
640
+ # end
641
+ # end
642
+ end
643
+ end
644
+
645
+ task :create_cache do
646
+ next if File.directory?(File.expand_path(fetch(:local_cache) + '/.git'))
647
+ run_locally do
648
+ execute :git, 'clone', fetch(:repo_url), fetch(:local_cache)
649
+ end
650
+ end
651
+
652
+ desc "stage the repository in a local directory"
653
+ task :stage => [ :create_cache ] do
654
+ run_locally do
655
+ within fetch(:local_cache) do
656
+ execute :git, "fetch", "--quiet", "--all", "--prune"
657
+ execute :git, "reset", "--hard", "origin/#{fetch(:branch)}"
658
+ end
659
+ end
660
+ end
661
+
662
+ desc "stage and rsync to the server"
663
+ task :sync => [ :stage ] do
664
+ release_roles(:all).each do |role|
665
+
666
+ user = role.user || fetch(:user)
667
+ user = user + "@" unless user.nil?
668
+
669
+ rsync_args = []
670
+ rsync_args.concat fetch(:rsync_options)
671
+ rsync_args.concat fetch(:rsync_include, []).map{|e| "--include #{e}"}
672
+ rsync_args.concat fetch(:rsync_exclude, []).map{|e| "--exclude #{e}"}
673
+ rsync_args << fetch(:local_cache) + "/"
674
+ rsync_args << "#{user}#{role.hostname}:#{remote_cache.call}"
675
+
676
+ run_locally do
677
+ execute :rsync, *rsync_args
678
+ end
679
+
680
+ on roles(:app) do
681
+ new_artrails_capistrano_run( "chmod +r+w+x -R #{remote_cache.call}" )
682
+ new_artrails_capistrano_run( "chmod g+w -R #{remote_cache.call}" )
683
+ new_artrails_capistrano_run( "chgrp -R mongrel #{remote_cache.call}" )
684
+ end
685
+ end
686
+ end
687
+
688
+ desc "stage, rsync to the server, and copy the code to the releases directory"
689
+ task :release => [ :sync ] do
690
+ copy = %(#{copy_command} "#{remote_cache.call}/" "#{release_path}/")
691
+ on release_roles(:all) do
692
+ new_artrails_capistrano_run copy
693
+ end
694
+ end
695
+
696
+ desc "Copy repo to releases"
697
+ # task create_release: :'git:update' do
698
+ # on release_roles :all do
699
+ # with fetch(:git_environmental_variables) do
700
+ # within repo_path do
701
+ # execute :mkdir, "-p", release_path
702
+ # git_plugin.archive_to_release_path
703
+ # end
704
+ # end
705
+ # end
706
+ # end
707
+ task create_release: [:release] do
708
+ # expected by the framework, delegate to better named task
709
+ end
710
+
711
+ Rake::Task['git:set_current_revision'].clear_actions
712
+ desc "Determine the revision that will be deployed"
713
+ # task :set_current_revision do
714
+ # on release_roles :all do
715
+ # within repo_path do
716
+ # with fetch(:git_environmental_variables) do
717
+ # set :current_revision, git_plugin.fetch_revision
718
+ # end
719
+ # end
720
+ # end
721
+ # end
722
+ task :set_current_revision do
723
+ run_locally do
724
+ run_locally do
725
+ set :current_revision, capture(:git, 'rev-parse', fetch(:branch))
726
+ end
727
+ end
728
+ end
729
+ end
730
+ end
731
+
732
+ # hooks
733
+ before 'deploy:updating', "artrails:set_current_revision"
734
+ before "deploy:web_server:restart", "maintenance:on"
735
+ after 'deploy:finished', 'artrails:update_versions_html'
736
+ after 'deploy:publishing', 'deploy:web_server:restart'
737
+ after "deploy:updated", "artrails:symlink:config"
738
+ after "deploy:symlink:release", "artrails:symlink:log"
739
+ after "maintenance:on", "deploy:isItWorking:deactivate"
740
+ after "maintenance:off", "deploy:isItWorking:activate"
741
+ after "maintenance:off", "artrails:check_is_it_working"
742
+ after "deploy:cleanup", "deploy:tag"