chicken_soup 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,17 @@
1
1
  Chicken Soup... for the Deployment Soul
2
2
  ================================
3
3
 
4
- TODO
4
+ Installation
5
+ ------
6
+ Add `require 'chicken_soup'` to your deploy.rb file.
7
+
8
+ Assumptions
9
+ ------
10
+ You're deploying with RVM
11
+ You have a `db:backup` task (link to mine)
12
+ You have a `db:seed` task (link to mine)
13
+ You have a `db:samplize` task (link to mine)
14
+ You have a non-priviledged `deployment` user and a priviledged `manager` user. The `manager` user has sudo capabilities.
5
15
 
6
16
  Issues
7
17
  ------
data/chicken_soup.gemspec CHANGED
@@ -28,10 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.require_paths = ["lib"]
29
29
  #= Manifest =#
30
30
 
31
- s.add_dependency('capistrano', '~> 3.0.3')
31
+ s.add_dependency('capistrano', '~> 2.5.19')
32
32
 
33
33
  s.add_development_dependency('bundler', '~> 1.0.10')
34
- s.add_development_dependency('rspec', '~> 2.4')
35
- s.add_development_dependency('rake', '~> 0.8.7')
36
- s.add_development_dependency('simplecov', '~> 0.3.9')
37
34
  end
@@ -0,0 +1,235 @@
1
+ ######################################################################
2
+ # APACHE TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ on :start, 'apache:environment_detection'
6
+
7
+ run_task 'web_server:stop', :as => 'manager'
8
+ run_task 'web_server:start', :as => 'manager'
9
+ run_task 'web_server:restart', :as => 'manager'
10
+
11
+ run_task 'website:install', :as => 'manager'
12
+ run_task 'website:remove', :as => 'manager'
13
+ run_task 'website:enable', :as => 'manager'
14
+ run_task 'website:disable', :as => 'manager'
15
+
16
+ namespace :deploy do
17
+ namespace :web do
18
+ desc <<-DESC
19
+ Enables the website's application by removing the maintenance page.
20
+ DESC
21
+ task :enable do
22
+ website.maintenance_mode.disable
23
+ end
24
+
25
+ desc <<-DESC
26
+ Disables the website's application by installing the maintenance page.
27
+ DESC
28
+ task :disable do
29
+ website.maintenance_mode.enable
30
+ end
31
+ end
32
+ end
33
+
34
+ namespace :web_server do
35
+ desc "Stop Apache"
36
+ task :stop do
37
+ apache.stop
38
+ end
39
+
40
+ desc "Start Apache"
41
+ task :start do
42
+ apache.start
43
+ end
44
+
45
+ desc "Restart Apache"
46
+ task :restart do
47
+ apache.restart
48
+ end
49
+ end
50
+
51
+ namespace :website do
52
+ desc "Creates the site configuration for the files."
53
+ task :create do
54
+ apache.virtual_host.install
55
+ end
56
+
57
+ desc "Completely removes the site configuration from the server (but leaves the files.)"
58
+ task :remove do
59
+ apache.virtual_host.remove
60
+ end
61
+
62
+ desc "Enable Site"
63
+ task :enable do
64
+ apache.website.enable
65
+ end
66
+
67
+ desc "Disable Site"
68
+ task :disable do
69
+ apache.website.disable
70
+ end
71
+
72
+ namespace :maintenance_mode do
73
+ desc <<-DESC
74
+ Makes the application web-accessible again. Removes the \
75
+ "maintenance.html" page generated by deploy:web:disable, which (if your \
76
+ web servers are configured correctly) will make your application \
77
+ web-accessible again.
78
+ DESC
79
+ task :disable, :except => { :no_release => true } do
80
+ run "rm #{shared_path}/system/maintenance.html"
81
+ end
82
+
83
+ desc <<-DESC
84
+ Present a maintenance page to visitors. Disables your application's web \
85
+ interface by writing a "maintenance.html" file to each web server. The \
86
+ servers must be configured to detect the presence of this file, and if \
87
+ it is present, always display it instead of performing the request.
88
+
89
+ By default, the maintenance page will just say the site is down for \
90
+ "maintenance", and will be back "shortly", but you can customize the \
91
+ page by specifying the REASON and UNTIL environment variables:
92
+
93
+ $ cap deploy:web:disable \\
94
+ REASON="hardware upgrade" \\
95
+ UNTIL="12pm Central Time"
96
+
97
+ Further customization will require that you write your own task.
98
+ DESC
99
+ task :enable, :except => { :no_release => true } do
100
+ on_rollback { rm "#{shared_path}/system/maintenance.html" }
101
+
102
+ require 'erb'
103
+ deadline, reason = ENV['UNTIL'], ENV['REASON']
104
+
105
+ template = File.read("./app/views/layouts/maintenance.html.erb")
106
+ maintenance_page = ERB.new(template).result(binding)
107
+
108
+ put maintenance_page, "#{shared_path}/system/maintenance.html", :mode => 0644
109
+ end
110
+ end
111
+ end
112
+
113
+ namespace :apache do
114
+ desc "[internal] Checks to see what type of Apache installation is running on the remote."
115
+ task :environment_detection do
116
+ find_apache_control_script
117
+
118
+ if apache_control_script =~ /apache2/
119
+ set :apache_enable_script, "a2ensite"
120
+ set :apache_disable_script, "a2dissite"
121
+ end
122
+ end
123
+
124
+ desc "[internal] Starts the Apache webserver"
125
+ task :start do
126
+ run "#{sudo} #{apache_control_script} start"
127
+ end
128
+
129
+ desc "[internal] Stops the Apache webserver"
130
+ task :stop do
131
+ run "#{sudo} #{apache_control_script} stop"
132
+ end
133
+
134
+ desc "[internal] Stops the Apache webserver"
135
+ task :restart do
136
+ run "#{sudo} #{apache_control_script} restart"
137
+ end
138
+
139
+ desc "[internal] Reloads the Apache configurations."
140
+ task :reload do
141
+ run "#{sudo} #{apache_control_script} reload"
142
+ end
143
+
144
+ namespace :website do
145
+ desc "[internal] Enables the Apache site on the server level."
146
+ task :enable do
147
+ abort "Sorry, auto-enabling sites is not supported on your version of Apache." unless exists?(:apache_enable_script)
148
+
149
+ run "#{sudo} #{apache_enable_script} #{deploy_name}"
150
+ apache.reload
151
+ end
152
+
153
+ desc "[internal] Disables the Apache site on the server level."
154
+ task :disable do
155
+ abort "Sorry, auto-disabling sites is not supported on your version of Apache." unless exists?(:apache_disable_script)
156
+
157
+ run "#{sudo} #{apache_disable_script} #{deploy_name}"
158
+ apache.reload
159
+ end
160
+ end
161
+
162
+ namespace :virtual_host do
163
+ desc "[internal] Install Virtual Host"
164
+ task :install do
165
+ abort "Sorry, auto-installing sites is not supported on your version of Apache." unless exists?(:apache_disable_script)
166
+
167
+ virtual_host_config = <<-VHOST
168
+ <VirtualHost #{web_server_ip}:443>
169
+ ServerName #{deploy_name}
170
+ DocumentRoot #{deploy_to}/current/public
171
+
172
+ SSLEngine on
173
+ SSLCertificateFile /etc/ssl/certs/#{domain}.crt
174
+ SSLCertificateKeyFile /etc/ssl/certs/#{domain}.key
175
+
176
+ RailsEnv #{rails_env}
177
+ RackEnv #{rails_env}
178
+
179
+ <Directory "#{deploy_to}/current/public">
180
+ Options FollowSymLinks -MultiViews
181
+ AllowOverride all
182
+ Order allow,deny
183
+ Allow from all
184
+ </Directory>
185
+
186
+ RewriteEngine On
187
+
188
+ ErrorDocument 503 /system/maintenance.html
189
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
190
+ RewriteCond %{SCRIPT_FILENAME} !maintenance.html
191
+ RewriteCond %{REQUEST_URI} !^/images/
192
+ RewriteCond %{REQUEST_URI} !^/robots.txt
193
+ RewriteCond %{REQUEST_URI} !^/sitemap
194
+ RewriteRule ^.*$ - [redirect=503,last]
195
+
196
+ ErrorLog /var/log/apache2/#{application}-errors.log
197
+
198
+ LogLevel warn
199
+
200
+ CustomLog /var/log/apache2/#{application}-access.log combined
201
+ ServerSignature On
202
+ </VirtualHost>
203
+
204
+ <VirtualHost #{web_server_ip}:80>
205
+ ServerName #{deploy_name}
206
+
207
+ Redirect permanent / https://#{deploy_name}
208
+ </VirtualHost>
209
+ VHOST
210
+
211
+ put virtual_host_config, "#{user_home}/#{deploy_name}"
212
+ run "#{sudo} mv #{user_home}/#{deploy_name} /etc/apache2/sites-available"
213
+ run "#{sudo} /etc/init.d/apache2 reload"
214
+ end
215
+
216
+ desc "[internal] Remove Virtual Host"
217
+ task :remove do
218
+ abort "Sorry, auto-removing sites is not supported on your version of Apache." unless exists?(:apache_disable_script)
219
+
220
+ run "#{sudo} rm /etc/apache2/sites-available/#{deploy_name}"
221
+ run "#{sudo} /etc/init.d/apache2 reload"
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ def find_apache_control_script
228
+ if remote_file_exists?("/usr/sbin/apachectl")
229
+ set :apache_control_script, "/usr/sbin/apachectl"
230
+ elsif remote_file_exists?("/usr/sbin/apache2")
231
+ set :apache_control_script, "/usr/sbin/apache2"
232
+ end
233
+
234
+ abort "Couldn't figure out your version of Apache" unless exists?(:apache_control_script)
235
+ end
@@ -0,0 +1,64 @@
1
+ ######################################################################
2
+ # BUNDLER TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ _cset :gem_packager_version, `gem list bundler`.match(/\((.*)\)/)[1]
6
+ set :rake, 'bundle exec rake'
7
+
8
+ before 'gems:install', 'bundler:install'
9
+
10
+ namespace :gems do
11
+ desc "Install Bundled Gems"
12
+ task :install do
13
+ run "cd #{current_release} && bundle install --gemfile #{current_release}/Gemfile --path #{shared_path}/bundle --deployment --quiet --without development test"
14
+ end
15
+
16
+ desc "Update Bundled Gems"
17
+ task :update do
18
+ raise "I'm sorry Dave, but I can't let you do that. I have full control over production." if rails_env == 'production'
19
+
20
+ run "cd #{current_release} && bundle update"
21
+ end
22
+ end
23
+
24
+ namespace :bundler do
25
+ desc "Install Bundler"
26
+ task :install do
27
+ run_with_rvm "#{ruby_version}@global", "gem install bundler --version #{gem_packager_version} --no-ri --no-rdoc && gem cleanup bundler"
28
+ end
29
+ end
30
+ end
31
+
32
+ ######################################################################
33
+ # BUNDLER ENVIRONMENT CHECKS #
34
+ ######################################################################
35
+ Capistrano::Configuration.instance(:must_exist).load do
36
+ namespace :environment do
37
+ namespace :check do
38
+ desc <<-DESC
39
+ [internal] Checks to see if all necessary Bundler environment variables have been set up.
40
+ DESC
41
+ task :bundler do
42
+ required_variables = [
43
+ :gem_packager_version
44
+ ]
45
+
46
+ verify_variables(required_variables)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ ######################################################################
53
+ # DEFAULT BUNDLER SETUP #
54
+ ######################################################################
55
+ Capistrano::Configuration.instance(:must_exist).load do
56
+ namespace :environment do
57
+ namespace :defaults do
58
+ desc "[internal] Sets intelligent defaults for Bundler deployments."
59
+ task :bundler do
60
+ _cset :bundler_version, `gem list bundler`.match(/\((.*)\)/)[1]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,65 @@
1
+ ######################################################################
2
+ # GIT TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ # before 'deploy:cleanup', 'deploy:tag'
6
+
7
+ namespace :deploy do
8
+ desc <<-DESC
9
+ Tags the deployed Git commit with the timestamp and environment it was deployed to.
10
+
11
+ The tag is auto-pushed to whatever `remote` is set to as well as `origin`.
12
+ Tag push happens in the background so it won't slow down deployment.
13
+ DESC
14
+ task :tag do
15
+ timestamp_string_without_seconds = Time.now.strftime("%Y%m%d%H%M")
16
+ tag_name = "deployed_to_#{rails_env}_#{timestamp_string_without_seconds}"
17
+
18
+ `git tag -a -m "Tagging deploy to #{rails_env} at #{timestamp_string_without_seconds}" #{tag_name} #{branch}`
19
+ `git push #{remote} --tags > /dev/null 2>&1 &`
20
+ `git push origin --tags > /dev/null 2>&1 &`
21
+ end
22
+ end
23
+ end
24
+
25
+ ######################################################################
26
+ # GIT ENVIRONMENT CHECK #
27
+ ######################################################################
28
+ Capistrano::Configuration.instance(:must_exist).load do
29
+ namespace :environment do
30
+ namespace :defaults do
31
+ desc "[internal] Sets intelligent version control defaults for deployments"
32
+ task :git do
33
+ _cset :github_account, ENV["USER"]
34
+ _cset :deploy_via, :remote_cache
35
+
36
+ set :scm, :git
37
+ set(:repository) {"git@github.com:#{github_account}/#{application}.git"}
38
+ set(:branch) { `git branch`.match(/\* (\S+)\s/m)[1] || raise("Couldn't determine current branch") }
39
+ set(:remote) { `git remote`.match(/(\S+)\s/m)[1] || raise("Couldn't determine default remote repository") }
40
+ ssh_options[:forward_agent] = true
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ ######################################################################
47
+ # DEFAULT GIT SETUP #
48
+ ######################################################################
49
+ Capistrano::Configuration.instance(:must_exist).load do
50
+ namespace :environment do
51
+ namespace :defaults do
52
+ desc "[internal] Sets intelligent version control defaults for deployments"
53
+ task :git do
54
+ _cset :github_account, ENV["USER"]
55
+ _cset :deploy_via, :remote_cache
56
+
57
+ set :scm, :git
58
+ set(:repository) {"git@github.com:#{github_account}/#{application}.git"}
59
+ set(:branch) { `git branch`.match(/\* (\S+)\s/m)[1] || raise("Couldn't determine current branch") }
60
+ set(:remote) { `git remote`.match(/(\S+)\s/m)[1] || raise("Couldn't determine default remote repository") }
61
+ ssh_options[:forward_agent] = true
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,286 @@
1
+ ######################################################################
2
+ # HEROKU TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ heroku_tasks = [
6
+ "heroku:credentials",
7
+ "heroku:credentials:default",
8
+ "deploy",
9
+ "deploy:default",
10
+ "deploy:initial",
11
+ "deploy:restart",
12
+ "deploy:migrate",
13
+ "deploy:rollback",
14
+ "deploy:rollback:default",
15
+ "deploy:web:enable",
16
+ "deploy:web:disable",
17
+ "website:install",
18
+ "website:remove",
19
+ "db:drop",
20
+ "db:backup",
21
+ "db:reset_and_seed",
22
+ "db:seed",
23
+ "shell",
24
+ "invoke"
25
+ ]
26
+
27
+ on :start, "heroku:credentials", :only => heroku_tasks
28
+ on :start, "heroku:raise_error", :except => heroku_tasks
29
+
30
+ namespace :heroku do
31
+ namespace :domain do
32
+ desc <<-DESC
33
+ Installs a new domain for the application on the Heroku server.
34
+ DESC
35
+ task :install do
36
+ `heroku domains:add #{deploy_name}`
37
+ end
38
+
39
+ desc <<-DESC
40
+ Removes the domain for the application from the Heroku server.
41
+ DESC
42
+ task :remove do
43
+ `heroku domains:remove #{deploy_name}`
44
+ end
45
+
46
+ namespace :addon do
47
+ desc <<-DESC
48
+ Add the Custom Domain Addon to the server.
49
+ DESC
50
+ task :install do
51
+ `heroku addons:add custom_domains:basic`
52
+ end
53
+
54
+ desc <<-DESC
55
+ Removes the Custom Domain Addon from the server.
56
+ DESC
57
+ task :remove do
58
+ `heroku addons:remove custom_domains:basic`
59
+ end
60
+ end
61
+ end
62
+
63
+ namespace :credentials do
64
+ desc <<-DESC
65
+ Selects the correct Heroku credentials for use given the current user.
66
+
67
+ If a credentials file already exists, it is backed up.
68
+ DESC
69
+ task :default do
70
+ if File.exist? heroku_credentials_file
71
+ heroku.credentials.backup
72
+ end
73
+
74
+ if File.exist? "#{heroku_credentials_path}/#{user}_credentials"
75
+ heroku.credentials.switch
76
+ else
77
+ heroku.credentials.create
78
+ end
79
+ end
80
+
81
+ desc <<-DESC
82
+ [internal] Backs up the current credentials file.
83
+ DESC
84
+ task :backup do
85
+ account = File.readlines(heroku_credentials_file)[0].chomp
86
+ File.rename(heroku_credentials_file, "#{heroku_credentials_path}/#{account}_credentials")
87
+ end
88
+
89
+ desc <<-DESC
90
+ [internal] Creates a Heroku credentials file.
91
+ DESC
92
+ task :create do
93
+ `if [ ! -d #{heroku_credentials_path} ]; then mkdir -p #{heroku_credentials_path}; fi`
94
+ `echo #{user} > #{heroku_credentials_file}`
95
+ `echo #{password} >> #{heroku_credentials_file}`
96
+ end
97
+
98
+ desc <<-DESC
99
+ [internal] Switches the credentials file to either the current use or the
100
+ name specified by the `HEROKU_ACCOUNT` environment variable.
101
+ DESC
102
+ task :switch do
103
+ account_to_switch_to = ENV['HEROKU_ACCOUNT'] || user
104
+ File.rename("#{heroku_credentials_path}/#{account_to_switch_to}_credentials", heroku_credentials_file)
105
+ end
106
+ end
107
+
108
+ desc <<-DESC
109
+ [internal] Raises an error if someone tries to run a task other than those
110
+ that are valid for a Heroku deployment.
111
+ DESC
112
+ task :raise_error do
113
+ raise "Deploying the #{rails_env} environment to Heroku. This command is invalid."
114
+ end
115
+ end
116
+
117
+ namespace :deploy do
118
+ desc <<-DESC
119
+ The standard deployment task.
120
+
121
+ It will check out a new release of the code, run any pending migrations and
122
+ restart the application.
123
+ DESC
124
+ task :default do
125
+ `git push heroku #{branch}`
126
+ deploy.migrate
127
+ deploy.restart
128
+ end
129
+
130
+ desc <<-DESC
131
+ Restarts the application.
132
+ DESC
133
+ task :restart do
134
+ `heroku restart`
135
+ end
136
+
137
+ desc <<-DESC
138
+ Runs the migrate rake task.
139
+ DESC
140
+ task :migrate do
141
+ `heroku rake db:migrate`
142
+ end
143
+
144
+ desc <<-DESC
145
+ Rolls back to a previous version and restarts.
146
+ DESC
147
+ namespace :rollback do
148
+ task :default do
149
+ `heroku rollback`
150
+ deploy.restart
151
+ end
152
+ end
153
+
154
+ namespace :web do
155
+ desc "Removes the maintenance page to resume normal site operation."
156
+ task :enable do
157
+ `heroku maintenance:off`
158
+ end
159
+
160
+ desc "Diplays the maintenance page."
161
+ task :disable do
162
+ `heroku maintenance:on`
163
+ end
164
+ end
165
+
166
+ desc "Prepare the server for deployment."
167
+ task :initial do
168
+ website.install
169
+
170
+ heroku.domain.addon.install
171
+ db.backup.addon.install
172
+
173
+ heroku.domain.install
174
+
175
+ `heroku config:add BUNDLE_WITHOUT="development:test"`
176
+ deploy.default
177
+ end
178
+ end
179
+
180
+ namespace :website do
181
+ desc "Installs the application on Heroku"
182
+ task :install do
183
+ `heroku create #{application}`
184
+ end
185
+
186
+ desc "Completely removes application from Heroku"
187
+ task :remove do
188
+ `heroku destroy --confirm #{application}`
189
+ end
190
+ end
191
+
192
+ namespace :db do
193
+ desc "Removes the DB from the Server. Also removes the user."
194
+ task :drop do
195
+ `heroku pg:reset`
196
+ end
197
+
198
+ namespace :backup do
199
+ desc "Backup the database"
200
+ task :default do
201
+ `heroku pgbackups:capture`
202
+ end
203
+
204
+ namespace :addon do
205
+ desc <<-DESC
206
+ Add the Postgres Backups Addon to the server.
207
+ DESC
208
+ task :install do
209
+ `heroku addons:add pgbackups:basic`
210
+ end
211
+
212
+ desc <<-DESC
213
+ Removes the Postgres Backups Addon from the server.
214
+ DESC
215
+ task :remove do
216
+ `heroku addons:remove pgbackups:basic`
217
+ end
218
+ end
219
+ end
220
+
221
+ desc "Reset database and seed fresh"
222
+ task :reset_and_seed do
223
+ raise "I'm sorry Dave, but I can't let you do that. I have full control over production." if rails_env == 'production'
224
+ db.backup
225
+ `heroku pg:reset`
226
+ `heroku rake db:seed`
227
+ end
228
+
229
+ desc "Seed database"
230
+ task :seed do
231
+ raise "I'm sorry Dave, but I can't let you do that. I have full control over production." if rails_env == 'production'
232
+ db.backup
233
+ `heroku rake db:seed`
234
+ end
235
+ end
236
+
237
+ desc "Begin an interactive Heroku session."
238
+ task :shell do
239
+ `heroku shell`
240
+ end
241
+
242
+ desc "Invoke a single command on the Heroku server."
243
+ task :invoke do
244
+ `heroku invoke #{ENV['COMMAND']}`
245
+ end
246
+ end
247
+
248
+ ######################################################################
249
+ # HEROKU ENVIRONMENT CHECKS #
250
+ ######################################################################
251
+ Capistrano::Configuration.instance(:must_exist).load do
252
+ namespace :environment do
253
+ namespace :check do
254
+ desc <<-DESC
255
+ [internal] Checks to see if all necessary Heroku environment variables have been set up.
256
+ DESC
257
+ task :heroku do
258
+ required_variables = [
259
+ :deploy_name,
260
+ :user,
261
+ :heroku_credentials_path,
262
+ :heroku_credentials_file
263
+ ]
264
+
265
+ verify_variables(required_variables)
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ ######################################################################
272
+ # DEFAULT HEROKU ENVIRONMENT SETUP #
273
+ ######################################################################
274
+ Capistrano::Configuration.instance(:must_exist).load do
275
+ namespace :environment do
276
+ namespace :defaults do
277
+ desc "[internal] Sets intelligent defaults for Heroku deployments"
278
+ task :heroku do
279
+ _cset :heroku_credentials_path, "#{ENV["HOME"]}/.heroku"
280
+ _cset :heroku_credentials_file, "#{heroku_credentials_path}/credentials"
281
+
282
+ _cset(:password) {Capistrano::CLI.password_prompt("Encrypted Heroku Password: ")}
283
+ end
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,6 @@
1
+ ######################################################################
2
+ # HOPTOAD TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ # require 'hoptoad_notifier/capistrano'
6
+ end