Created
September 11, 2012 11:09
-
-
Save taktran/3697640 to your computer and use it in GitHub Desktop.
Ship it! rake task. Some details about the rationale here: http://blog.pebblecode.com/post/32263926012/ship-it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ship it! rake task | |
# | |
# Merge branch (master by default) to deployment branch, and deploy to server. | |
# | |
# Prerequisite: | |
# | |
# * Declare all deployment branches in `ALL_DEPLOYMENT_BRANCHES` | |
# * Declare deploy only branches in `DEPLOY_ONLY_BRANCHES` (ie, does not merge master) | |
# * Modify `Deploy.command` function as necessary | |
# | |
# Usage: | |
# | |
# # To initalise local branch and push to origin | |
# bundle exec rake shipit:init[deployment-branch] | |
# | |
# # Setup heroku if required | |
# bundle exec rake deploy:init:heroku[name] | |
# | |
# # Do work on `master`, and commit | |
# # Merge `master` to `deployment-branch`, and deploy with: | |
# bundle exec rake shipit[deployment-branch] | |
# | |
# # Do work on `some-branch`, and commit | |
# # Merge `some-branch` to `deployment-branch`, and deploy with: | |
# bundle exec rake shipit:branch[some-branch,deployment-branch] | |
# | |
# Notes: | |
# | |
# * Merge conflicts may occur, which the rake tasks don't currently | |
# handle. You need to exercise your git-foo in these cases. | |
# | |
require 'fileutils' | |
ALL_DEPLOYMENT_BRANCHES = ["staging"] | |
DEPLOY_ONLY_BRANCHES = [] | |
module Deploy | |
# Remember to download the [heroku toolbelt first](https://toolbelt.heroku.com/) | |
def self.init_heroku(name) | |
Rake.sh "heroku create #{name}" | |
end | |
def self.command(branch) | |
# For capitrano - Assume that capistrano task is the same name as the branch | |
# "bundle exec cap #{branch} deploy" | |
# For heroku - Assume heroku is setup | |
"git push heroku #{branch}:master" | |
end | |
def self.branch!(branch) | |
Rake.sh self.command(branch) | |
end | |
end | |
module Git | |
def self.create_branch!(branch, &next_command) | |
Rake.sh "git checkout -b #{branch}", &next_command | |
end | |
# Since Git 1.7.0 | |
def self.push_new_branch_to_origin!(branch, &next_command) | |
Rake.sh "git push -u origin #{branch}", &next_command | |
end | |
def self.checkout!(branch, &next_command) | |
Rake.sh "git checkout #{branch}", &next_command | |
end | |
def self.merge!(branch, &next_command) | |
Rake.sh "git merge #{branch}", &next_command | |
end | |
def self.push_origin!(local_branch, remote_branch) | |
Rake.sh "git push origin #{local_branch}:#{remote_branch}" | |
end | |
# Merge `from_branch` and push to remote server, and checkout `from_branch` at the end. | |
def self.merge_branch!(from_branch, to_branch) | |
run_push_origin = Proc.new do |ok, resp| | |
if ok | |
self.push_origin!(to_branch, to_branch) | |
self.checkout!(from_branch) | |
else | |
abort(resp.to_s) | |
end | |
end | |
run_merge = Proc.new do |ok, resp| | |
if ok | |
self.merge!(from_branch, &run_push_origin) | |
else | |
abort(resp.to_s) | |
end | |
end | |
# Checkout -> merge -> push origin | |
self.checkout! to_branch, &run_merge | |
end | |
end | |
desc "Merge master to branch, and push to origin server." | |
task "merge_master_and_push_to", [:branch] do |t, args| | |
Git.merge_branch!("master", args.branch) | |
end | |
desc "Deploy branch to server." | |
task :deploy, [:branch] do |t, args| | |
Deploy.branch!(args.branch) | |
end | |
namespace "deploy" do | |
desc "Initialise heroku" | |
task "init:heroku", [:name] do |t, args| | |
Deploy.init_heroku(args.name) | |
end | |
end | |
desc "Ship it! Merge master and push branch to origin (if not in `DEPLOY_ONLY_BRANCHES`), then deploy to the server." | |
task "shipit", [:branch] do |t, args| | |
if ALL_DEPLOYMENT_BRANCHES.include? args.branch | |
unless DEPLOY_ONLY_BRANCHES.include? args.branch | |
Rake::Task["merge_master_and_push_to"].invoke(args.branch) | |
end | |
Rake::Task["deploy"].invoke(args.branch) | |
else | |
puts "Invalid deployment branch: #{args.branch}" | |
puts "Available deployment branches are: #{ALL_DEPLOYMENT_BRANCHES.to_s}" | |
end | |
end | |
namespace "shipit" do | |
desc "Initialise shipit with local branch, and push branch to origin server." | |
task "init", [:branch] do |t, args| | |
branch = args.branch | |
run_push_origin = Proc.new do |ok, resp| | |
if ok | |
Git.push_new_branch_to_origin!(branch) | |
else | |
abort(resp.to_s) | |
end | |
end | |
# Create local branch -> push to branch to origin | |
Git.create_branch!(branch, &run_push_origin) | |
end | |
desc "Merge branch to deployment branch, push to remote server, and deploy." | |
task :branch, [:from_branch, :deploy_branch] do |t, args| | |
from_branch = args.from_branch | |
deploy_branch = args.deploy_branch | |
if ALL_DEPLOYMENT_BRANCHES.include? deploy_branch | |
Git.merge_branch!(from_branch, deploy_branch) | |
Rake::Task["deploy"].invoke(deploy_branch) | |
else | |
puts "Invalid deployment branch: #{args.branch}" | |
puts "Available deployment branches are: #{ALL_DEPLOYMENT_BRANCHES.to_s}" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment