heroku_tasks 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,67 @@
1
+ = Installation
2
+
3
+ Add it to your Gemfile (inside development group)
4
+
5
+ gem 'heroku_tasks', :git => 'git://github.com/thibaudgg/heroku_tasks.git'
6
+
7
+ = Configuration
8
+
9
+ Setup staging/production branch (here from remote)
10
+
11
+ git checkout -t origin/production
12
+ git checkout -t origin/staging
13
+
14
+ Create config/heroku.yml file and edit it
15
+
16
+ rails generate heroku_tasks:config
17
+
18
+ = Deploy procedure
19
+
20
+ Merge your last work in staging branch
21
+
22
+ git checkout staging
23
+ git pull origin staging
24
+ git merge master
25
+
26
+ Regenerate your assets if you're using {Jammit}[http://documentcloud.github.com/jammit/] (and you should)
27
+
28
+ rake deploy:assets
29
+
30
+ Push your code to staging heroku app
31
+
32
+ rake deploy:staging
33
+ or
34
+ rake deploy:staging:migrations
35
+
36
+ If your staging app is still alive
37
+
38
+ git checkout production
39
+ git pull origin production
40
+ git merge staging
41
+
42
+ Activate maintenance page on production and wait for it (Optional, ie. with migrations)
43
+
44
+ heroku maintenance:on --app production_app
45
+
46
+ Push your code to production app
47
+
48
+ rake deploy:production
49
+ or
50
+ rake deploy:production:migrations
51
+
52
+ Don't forget to remove maintenance page if needed
53
+
54
+ heroku maintenance:off --app production_app
55
+
56
+ Back to work (after some rest!)
57
+
58
+ git checkout master
59
+ git merge production
60
+
61
+ = Rollback
62
+
63
+ If you met any problems
64
+
65
+ rake deploy:staging:rollback
66
+ or
67
+ rake deploy:production:rollback
@@ -0,0 +1,16 @@
1
+ module HerokuTasks
2
+ module Generators
3
+ class ConfigGenerator < Rails::Generators::Base
4
+ desc "Creates a HerokuTasks configuration file at config/heroku.yml"
5
+
6
+ def self.source_root
7
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
8
+ end
9
+
10
+ def create_config_file
11
+ template 'heroku.yml', File.join('config', "heroku.yml")
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ staging: site-staging
2
+ production: site
3
+ production_url: http://site.com # for jammit assets
4
+ git_repo: git@site.git # for git tag
@@ -0,0 +1,20 @@
1
+ module HerokuTasks
2
+ require 'heroku_tasks/railtie' if defined?(Rails)
3
+
4
+ class << self
5
+
6
+ def method_missing(name)
7
+ yml[name.to_s]
8
+ end
9
+
10
+ private
11
+
12
+ def yml
13
+ config_path = Rails.root.join('config', 'heroku.yml')
14
+ @yml_options ||= YAML::load_file(config_path)
15
+ rescue
16
+ raise "\nconfig/heroku.yml not found. To generate one run: rails generate heroku_tasks:config\n"
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'heroku_tasks'
2
+ require 'rails'
3
+
4
+ module HerokuTasks
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ load "tasks/deploy.rake"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module HerokuTasks
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,158 @@
1
+ namespace :deploy do
2
+
3
+ desc "Prepare jammit assets before deploy"
4
+ task :assets do
5
+ system "bundle exec jammit -u #{HerokuTasks.production_url} -f"
6
+
7
+ Dir.glob("public/assets/*.css").each do |file|
8
+ puts file
9
+ buffer = File.new(file,'r').read.gsub(/@media screen and\(/,"@media screen and (")
10
+ File.open(file,'w') {|fw| fw.write(buffer)}
11
+ end
12
+
13
+ system "git add public/assets/*"
14
+ system "git commit public/assets/* -m 'Updated assets before deploy'"
15
+ end
16
+
17
+ desc "Heroku staging (#{HerokuTasks.staging}) deploy"
18
+ task :staging => [:set_staging_app, :push, :restart, :tag]
19
+
20
+ namespace :staging do
21
+ desc "Heroku staging (#{HerokuTasks.staging}) deploy with migration (and copy production db)"
22
+ task :migrations => [:set_staging_app, :push, :copy_production_db, :migrate, :restart, :tag]
23
+ desc "Heroku staging (#{HerokuTasks.staging}) rollback"
24
+ task :rollback => [:set_staging_app, :rollback, :restart]
25
+ end
26
+
27
+ desc "Heroku production (#{HerokuTasks.production}) deploy"
28
+ task :production => [:set_production_app, :push, :restart, :tag]
29
+
30
+ namespace :production do
31
+ desc "Heroku production (#{HerokuTasks.staging}) deploy with migration"
32
+ task :migrations => [:set_production_app, :push, :migrate, :restart, :tag]
33
+ desc "Heroku production (#{HerokuTasks.staging}) rollback"
34
+ task :rollback => [:set_production_app, :rollback, :restart]
35
+ end
36
+
37
+ # =======================
38
+ # = Don't call directly =
39
+ # =======================
40
+
41
+ task :set_staging_app do
42
+ APP = HerokuTasks.staging
43
+ TARGET = 'staging'
44
+ end
45
+ task :set_production_app do
46
+ APP = HerokuTasks.production
47
+ TARGET = 'production'
48
+ end
49
+
50
+ task :push do
51
+ timed do
52
+ puts "\nDeploying #{TARGET}'s branch to #{APP} on heroku ..."
53
+ system "git push git@heroku.com:#{APP}.git #{TARGET}:master"
54
+ end
55
+ end
56
+
57
+ task :restart do
58
+ timed do
59
+ puts "\nRestarting #{app_and_target} servers ..."
60
+ system "heroku restart --app #{APP}"
61
+ end
62
+ end
63
+
64
+ task :tag do
65
+ tag_and_push_release("#{prefix}#{normalized_date}")
66
+ end
67
+
68
+ task :migrate do
69
+ timed do
70
+ puts "\nRunning database migrations for #{app_and_target} ..."
71
+ system "heroku rake db:migrate --app #{APP}"
72
+ end
73
+ end
74
+
75
+ task :copy_production_db do
76
+ timed do
77
+ puts "\nCopying production database for #{app_and_target} ..."
78
+ system "heroku db:pull sqlite://backup.db --app #{HerokuTasks.production}"
79
+ system "heroku db:push sqlite://backup.db --app #{APP}"
80
+ end
81
+ end
82
+
83
+ task :rollback do
84
+ releases = `git tag`.split("\n").select { |t| t[0..prefix.length-1] == prefix }.sort
85
+
86
+ if releases.length >= 2
87
+ current_release = releases.last
88
+ previous_release = releases[-2]
89
+
90
+ started_at = Time.now.utc
91
+ puts "\nRolling back to '#{previous_release}' ..."
92
+
93
+ puts "\nChecking out '#{previous_release}' in a new branch on local git repo ..."
94
+ system "git checkout #{previous_release}"
95
+ system "git checkout -b #{previous_release}"
96
+
97
+ puts "\nRemoving tagged version '#{previous_release}' (now transformed in branch) ..."
98
+ delete_tagged_version(previous_release)
99
+
100
+ puts "\nPushing '#{previous_release}' to #{APP} on heroku/master ..."
101
+ system "git push git@heroku.com:#{APP}.git +#{previous_release}:master --force"
102
+ puts "Done"
103
+
104
+ puts "\nDeleting rollbacked release '#{current_release}' ..."
105
+ delete_tagged_version(current_release)
106
+
107
+ puts "\nRetagging release '#{previous_release}' ..."
108
+ tag_and_push_release(previous_release)
109
+
110
+ puts "\nTurning local repo checked out on master ..."
111
+ system "git checkout master"
112
+ puts "All done! Rolled back to '#{previous_release}' in #{Time.now.utc - started_at} seconds!"
113
+ else
114
+ puts "\nCan't roll back! You need at least 2 release to be able to rollback the last release!"
115
+ puts releases
116
+ end
117
+ end
118
+
119
+ def prefix
120
+ "#{APP}_#{TARGET}_release-"
121
+ end
122
+
123
+ def app_and_target
124
+ "#{APP} (#{TARGET})"
125
+ end
126
+
127
+ def delete_tagged_version(release_name)
128
+ timed do
129
+ system "git tag -d #{release_name}"
130
+ system "git push git@heroku.com:#{APP}.git :refs/tags/#{release_name}"
131
+ system "git push #{HerokuTasks.git_repo} :refs/tags/#{release_name}"
132
+ end
133
+ end
134
+
135
+ def tag_and_push_release(release_name)
136
+ timed do
137
+ puts "\nTagging release as '#{release_name}'"
138
+ system "git tag -a #{release_name} -m \"Heroku's tagged release\""
139
+ system "git push --tags git@heroku.com:#{APP}.git"
140
+ system "git push --tags #{HerokuTasks.git_repo}"
141
+ end
142
+ end
143
+
144
+ def normalized_date
145
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
146
+ end
147
+
148
+ def timed(&block)
149
+ if block_given?
150
+ start_time = Time.now.utc
151
+ yield
152
+ print "\tDone in #{Time.now.utc - start_time}s!\n\n"
153
+ else
154
+ print "\n\nYou must pass a block to this method!\n\n"
155
+ end
156
+ end
157
+
158
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heroku_tasks
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Thibaud Guillaume-Gentil
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-31 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: bundler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: Bundle of rake tasks to manage staging/production heroku deploy.
38
+ email:
39
+ - thibaud@thibaud.me
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - lib/generators/heroku_tasks/config/config_generator.rb
48
+ - lib/generators/heroku_tasks/config/templates/heroku.yml
49
+ - lib/heroku_tasks/railtie.rb
50
+ - lib/heroku_tasks/version.rb
51
+ - lib/heroku_tasks.rb
52
+ - lib/tasks/deploy.rake
53
+ - README.rdoc
54
+ has_rdoc: true
55
+ homepage: http://rubygems.org/gems/heroku_tasks
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 23
78
+ segments:
79
+ - 1
80
+ - 3
81
+ - 6
82
+ version: 1.3.6
83
+ requirements: []
84
+
85
+ rubyforge_project: heroku_tasks
86
+ rubygems_version: 1.3.7
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Bundle of rake tasks to manage staging/production heroku deploy
90
+ test_files: []
91
+