capistrano-ext-projectdx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ # we have to call this something else so
2
+ # we do not keep loading this file over and over
3
+ Capistrano::Configuration.instance.load do
4
+ load_paths << File.dirname(__FILE__)
5
+ load('projectdx.rb')
6
+ load('campfire.rb')
7
+ load('git_branch.rb')
8
+ load('misc.rb')
9
+ load('time.rb')
10
+ load('web.rb')
11
+ load('passenger.rb')
12
+ load('docs.rb')
13
+ load('cache.rb')
14
+ end
@@ -0,0 +1,8 @@
1
+ namespace :cache do
2
+ desc "Empty out shared cachedir and the cached javascript and css"
3
+ task :clean, :roles => :web do
4
+ run "shopt -s nullglob; cd #{current_path} && for i in ./public/javascripts/cache_*.js; do /bin/rm ${i}; done"
5
+ run "shopt -s nullglob; cd #{current_path} && for i in ./public/stylesheets/cache_*.css; do /bin/rm ${i}; done"
6
+ run "shopt -s nullglob; cd #{shared_path} && /bin/rm -rf cache/*"
7
+ end
8
+ end
@@ -0,0 +1,59 @@
1
+ namespace :misc do
2
+ def send_to_campfire(message)
3
+ begin
4
+ gem 'tinder'
5
+ rescue Gem::LoadError
6
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
7
+ puts ""
8
+ puts "not notifying because tinder not installed. Message is: '#{message}'"
9
+ puts ""
10
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
11
+ return
12
+ end
13
+ require 'tinder'
14
+ # for some reason, ssl isn't working.
15
+ begin
16
+ campfire = Tinder::Campfire.new(campfire_host, :ssl => true)
17
+ campfire.login(campfire_login, campfire_password)
18
+ rescue => e
19
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
20
+ puts ""
21
+ puts "Unable to login to campfire. Error is: '#{e}'"
22
+ puts "login: #{campfire_host}, #{campfire_login}, #{campfire_password}"
23
+ puts ""
24
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
25
+ return
26
+ end
27
+ begin
28
+ room = campfire.find_room_by_name(campfire_room)
29
+ rescue => e
30
+ logger.error("Trouble initalizing campfire room #{campfire_room}")
31
+ return
32
+ end
33
+ begin
34
+ room.speak(message)
35
+ rescue => e
36
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
37
+ puts ""
38
+ puts "Unable to send message to campfire. Message is: '#{message}'"
39
+ puts ""
40
+ puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
41
+ return
42
+ end
43
+ end
44
+ desc "[internal] Send campfire notifications on success"
45
+ task :send_success, :on_error => :continue do
46
+ t=end_time
47
+ time_msg=t.nil? ? '' : " in #{t} minutes"
48
+ send_to_campfire("#{Etc.getpwnam(Etc.getlogin)['gecos'].split.first} tried to deploy branch #{branch} to #{stage}. It succeeded#{time_msg}! :D")
49
+ end
50
+
51
+ desc "[internal] send notifications in case the deploy fails"
52
+ task :rollback_notification, :on_error => :continue do
53
+ on_rollback {
54
+ t=end_time
55
+ time_msg=t.nil? ? '' : " after #{t} minutes"
56
+ send_to_campfire("#{Etc.getpwnam(Etc.getlogin)['gecos'].split.first} tried to deploy branch #{branch} to #{stage}. It failed#{time_msg}. :.(")
57
+ }
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :deploy do
3
+ namespace :docs do
4
+ desc "update docs directory"
5
+ task :default do
6
+ run "cd #{current_path} && rake doc:local RDOC_DIR=#{docsdir}"
7
+ end
8
+ desc "force rebuild of docs directory"
9
+ task :rebuild do
10
+ run "/bin/rm -rf #{docsdir}"
11
+ top.deploy.docs.default
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ Capistrano::Configuration.instance.load do
2
+ def changed_in_git(filename)
3
+ `git diff --name-only`.grep(/^#{filename}$/).length > 0 ? true : false
4
+ end
5
+
6
+ def commit_of_rev(branch)
7
+ x=`git rev-parse --revs-only #{branch}`.chomp
8
+ return nil if x.empty?
9
+ return x
10
+ end
11
+
12
+ def commit_in_remote_branch?(commit,branch)
13
+ return false if commit.nil?
14
+ if %x{git branch -r --contains #{commit}}.grep(/^\s*origin\/#{branch}/).empty?
15
+ puts ""
16
+ puts "no rev matches #{commit} in the remote #{branch} branch(es)"
17
+ return false
18
+ end
19
+ true
20
+ end
21
+
22
+ def valid_commit?(commit)
23
+ return false if commit.nil?
24
+ if [ :production ].include? stage
25
+ return false unless commit_in_remote_branch?(commit,'production')
26
+ elsif [ :custbeta ].include? stage
27
+ return false unless commit_in_remote_branch?(commit,'custbeta')
28
+ end
29
+ return true
30
+ end
31
+
32
+ # returns the actual branch name, if it exists. nil if it does not
33
+ def remote_branch_name(branch)
34
+ return nil if branch.nil?
35
+ rem_branch = `git branch -r`.grep(/^\s*origin\/(v|)#{branch}$/)[0]
36
+ return nil if rem_branch.nil?
37
+ return rem_branch.sub(/^\s*origin\//, '').chomp
38
+ end
39
+
40
+ release = nil;
41
+ set :release_number do
42
+ commit=nil;
43
+ release=ENV[ 'DEPLOY_VERSION' ] if ENV[ 'DEPLOY_VERSION' ]
44
+ release=ENV['BUILD_VCS_NUMBER'][0,12] if ENV['BUILD_VCS_NUMBER']
45
+ commit = commit_of_rev(release)
46
+ while not valid_commit?(commit) do
47
+ release=Capistrano::CLI.ui.ask( 'Enter release number to deploy: ' )
48
+ commit=commit_of_rev(release)
49
+ end
50
+ commit
51
+ end
52
+
53
+ set :branch do
54
+ release_number
55
+ end
56
+
57
+ set :release_commit do
58
+ branch
59
+ end
60
+ end
@@ -0,0 +1,35 @@
1
+ namespace :misc do
2
+ desc "[internal] Send campfire notifications on success"
3
+ task :send_success, :on_error => :continue do
4
+ t=end_time
5
+ time_msg=t.nil? ? '' : " in #{t} minutes"
6
+ send_to_campfire("#{Etc.getpwnam(Etc.getlogin)['gecos'].split.first} tried to deploy branch #{branch} to #{stage}. It succeeded#{time_msg}! :D")
7
+ end
8
+
9
+ desc "[internal] send notifications in case the deploy fails"
10
+ task :rollback_notification, :on_error => :continue do
11
+ on_rollback {
12
+ t=end_time
13
+ time_msg=t.nil? ? '' : " after #{t} minutes"
14
+ send_to_campfire("#{Etc.getpwnam(Etc.getlogin)['gecos'].split.first} tried to deploy branch #{branch} to #{stage}. It failed#{time_msg}. :.(")
15
+ }
16
+ end
17
+ end
18
+
19
+ desc "Add trigers on migration to restore database from production state. Used for running stage deployments with optional restore."
20
+ task :restoredb do
21
+ before "deploy:migrate", "deploy:db:reset_nobackup"
22
+ after "deploy:db:reset_nobackup", "deploy:tables"
23
+ end
24
+
25
+ desc "Do full deploy of table updates"
26
+ task :full do
27
+ before "deploy:migrate", "deploy:tables"
28
+ end
29
+
30
+ namespace :rake do
31
+ desc "Allow running of remote rake tasks"
32
+ task :invoke do
33
+ run "cd #{deploy_to}/current && rake #{ENV['task']} RAILS_ENV=#{rails_env}"
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :deploy do
3
+ # these can be changed when passenger is on production
4
+ desc "Stop task is a no-op with passenger"
5
+ task :stop, :roles => :app do ; end
6
+
7
+ %w(start restart).each do |name|
8
+ desc "#{name} passenger on application"
9
+ task name, :roles => :app do
10
+ top.passenger.restart
11
+ end
12
+ end
13
+ end
14
+ namespace :passenger do
15
+ desc "Restart Passenger"
16
+ task :restart, :rols => :app do
17
+ run "touch #{current_path}/tmp/restart.txt"
18
+ if [ :production ].include? stage
19
+ run "curl -s -o /dev/null http://sonomacountyenergyaction.org/customers/2/geometries;true"
20
+ run "curl -s -o /dev/null http://sonomacountyenergyaction.org/customers/1/geometries;true"
21
+ else
22
+ run "curl -s -o /dev/null http:/sonoma.`hostname`/customers/2/geometries;true"
23
+ run "curl -s -o /dev/null http:/sonoma.`hostname`/customers/1/geometries;true"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,72 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :deploy do
3
+ desc "update selinux context"
4
+ task :selinux do
5
+ run "if [ -d #{release_path} ]; then
6
+ chcon -R -t httpd_sys_content_t #{release_path} ;
7
+ fi;
8
+ if [ -d #{current_path}/ ]; then
9
+ chcon -R -t httpd_sys_content_t #{current_path}/;
10
+ fi"
11
+ end
12
+
13
+ desc "install database.yml, and other things "
14
+ task :local_config do
15
+ run "cp #{release_path}/config/database.deploy.yml #{release_path}/config/database.yml"
16
+ case stage
17
+ when :alpha
18
+ run "rsync -a #{release_path}/features/ #{release_path}/public/features/"
19
+ run %Q{ /bin/ls -1 #{release_path}/public/features/ | /bin/awk -v dq='"' 'BEGIN{print "<!DOCTYPE HTML PUBLIC " dq "-//W3C//DTD HTML 4.01//EN" dq "\n" dq "http://www.w3.org/TR/html4/strict.dtd"dq">\n<body><table>"} /feature$/ {print "<tr><td><a href="dq $1 dq ">" $1 "</a></td></tr>"} END{print "</table></body>"}' > #{release_path}/public/features/index.html}
20
+ end
21
+ run "mkdir -p #{shared_path}/cache"
22
+ run "/bin/ln -nsf #{release_path}/../../shared/cache #{release_path}/public/cache"
23
+ #run "/bin/ln -nsf #{release_path} #{release_path}/../latest"
24
+ #run "/bin/ln -nsf #{shared_path}/config/database.yml #{release_path}/config/database.yml"
25
+ end
26
+
27
+ desc "Write Version file on server"
28
+ task :write_version_file, :roles => :web do
29
+ output=%Q{
30
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
31
+ "http://www.w3.org/TR/html4/strict.dtd">
32
+ <body>
33
+ <p>Release Branch: #{release_number}</p>
34
+ <p>Release Commit: #{release_commit}</p>
35
+ <p>Deployed on: #{Time.now.strftime('%m/%d/%Y at %H:%M %Z')}</p>
36
+ </body>
37
+ }
38
+ put(output, "#{current_path}/public/version.html")
39
+ end
40
+
41
+ desc "make some directories we like to have"
42
+ task :make_shared_dirs do
43
+ run "mkdir -p #{deploy_to}/shared/system"
44
+ run "mkdir -p #{deploy_to}/shared/config"
45
+ run "mkdir -p #{deploy_to}/shared/log/old"
46
+ run "mkdir -p #{deploy_to}/shared/pids"
47
+ run "mkdir -p #{deploy_to}/releases"
48
+ run "mkdir -p '#{shared_path}/config/payment_gateways'"
49
+ end
50
+
51
+ desc "remove old submodules from vendors directory"
52
+ task :cleanup_vendor do
53
+ run "cd #{deploy_to}/shared/cached-copy && git clean -dxf vendor"
54
+ end
55
+
56
+ before "deploy:update_code", "deploy:cleanup_vendor"
57
+ before "deploy:rollback:revision", "deploy:rollback_migrations"
58
+
59
+ desc "Rolls back database to migration level of the previously deployed release"
60
+ task :rollback_migrations, :roles => :db, :only => { :primary => true } do
61
+ if releases.length < 2
62
+ abort "could not rollback the code because there is no prior release"
63
+ else
64
+ rake = fetch(:rake, "rake")
65
+ rails_env = fetch(:rails_env, "production")
66
+ migrate_env = fetch(:migrate_env, "")
67
+ migrate_target = fetch(:migrate_target, :latest)
68
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate VERSION=`cd #{File.join(previous_release, 'db', 'migrate')} && ls -1 [0-9]*_*.rb | tail -1 | sed -e s/_.*$//`"
69
+ end
70
+ end
71
+ end #namespace deploy
72
+ end
@@ -0,0 +1,29 @@
1
+ def start_time
2
+ @begin = Time.now()
3
+ end
4
+
5
+ def end_time
6
+ if @begin.nil?
7
+ return nil
8
+ else
9
+ return to_minutes(Time.now() - @begin)
10
+ end
11
+ end
12
+
13
+ namespace :time do
14
+ desc "[internal] record the current time for later use"
15
+ task :begin do
16
+ start_time
17
+ end
18
+ desc "[internal] print the time elapsed since time:begin was executed"
19
+ task :finish do
20
+ how_long=end_time
21
+ if how_long.nil?
22
+ puts "You must run start_time before you can call end_time"
23
+ else
24
+ puts ""
25
+ puts "deploy took: #{end_time} minutes"
26
+ puts ""
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,53 @@
1
+ namespace :deploy do
2
+ namespace :web do
3
+ desc <<-DESC
4
+ Present a maintenance page to visitors. Disables your application's web \
5
+ interface by writing a "maintenance.html" file to each web server. The \
6
+ servers must be configured to detect the presence of this file, and if \
7
+ it is present, always display it instead of performing the request.
8
+
9
+ By default, the maintenance page will just say the site is down for \
10
+ "maintenance", and will be back "shortly", but you can customize the \
11
+ page by specifying the REASON environment variable:
12
+
13
+ $ cap deploy:web:disable \\
14
+ REASON="hardware upgrade"
15
+
16
+ Further customization will require that you write your own task.
17
+ DESC
18
+ #"/home/projectdx/projectdx-cms/current/public/system/maintenance.html"
19
+ maint_files=["#{shared_path}/system/maintenance.html",
20
+ ]
21
+
22
+ task :disable, :roles => :web, :except => { :no_release => true } do
23
+ require 'erb'
24
+ on_rollback { maint_files.each do |file|
25
+ run "if [ -e #{file} ]; then rm #{file}; fi"
26
+ end
27
+ }
28
+
29
+ reason = ENV['REASON']
30
+
31
+ template = File.read("public/maintenance.rhtml")
32
+ result = ERB.new(template).result(binding)
33
+ maint_files.each do |file|
34
+ dir=File.dirname(file)
35
+ put result, "/tmp/disable_cap", :mode => 0644
36
+ run "if [ -d #{dir} -a \! -e #{file} ]; then mv /tmp/disable_cap #{file}; fi"
37
+ run "chcon -t httpd_sys_content_t #{file}; true" # we ignore this since some hosts have home on nfs
38
+ end
39
+ end
40
+
41
+ desc <<-DESC
42
+ Makes the application web-accessible again. Removes the \
43
+ "maintenance.html" page generated by deploy:web:disable, which (if your \
44
+ web servers are configured correctly) will make your application \
45
+ web-accessible again.
46
+ DESC
47
+ task :enable, :roles => :web, :except => { :no_release => true } do
48
+ maint_files.each do |file|
49
+ run "if [ -e #{file} ]; then rm #{file}; fi"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ require 'capistrano'
2
+ Capistrano::Configuration.instance.load do
3
+ load_paths << File.dirname(__FILE__)+'/projectdx'
4
+ def to_minutes(seconds)
5
+ m = (seconds/60).floor
6
+ s = (seconds - (m * 60)).round
7
+ # add leading zero to one-digit minute
8
+ if m < 10
9
+ m = "0#{m}"
10
+ end
11
+ # add leading zero to one-digit second
12
+ if s < 10
13
+ s = "0#{s}"
14
+ end
15
+ # return formatted time
16
+ return "#{m}:#{s}"
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-ext-projectdx
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Darrell Fuhriman
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-06-16 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Local extensions to capistrano, which others may find useful
23
+ email:
24
+ - darrell@renewfund.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - lib/capistrano/ext/projectdx/all.rb
33
+ - lib/capistrano/ext/projectdx/cache.rb
34
+ - lib/capistrano/ext/projectdx/campfire.rb
35
+ - lib/capistrano/ext/projectdx/docs.rb
36
+ - lib/capistrano/ext/projectdx/git_branch.rb
37
+ - lib/capistrano/ext/projectdx/misc.rb
38
+ - lib/capistrano/ext/projectdx/passenger.rb
39
+ - lib/capistrano/ext/projectdx/projectdx.rb
40
+ - lib/capistrano/ext/projectdx/time.rb
41
+ - lib/capistrano/ext/projectdx/web.rb
42
+ - lib/capistrano/ext/projectdx.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/projectdx/capistrano-ext-projectdx
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 23
67
+ segments:
68
+ - 1
69
+ - 3
70
+ - 6
71
+ version: 1.3.6
72
+ requirements: []
73
+
74
+ rubyforge_project: capistrano-ext-projectdx
75
+ rubygems_version: 1.3.7
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Local extensions to capistrano, which others may find useful
79
+ test_files: []
80
+