heroku_tasks 0.1.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.
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
+