Skip to content

Instantly share code, notes, and snippets.

@mattheworiordan
Created February 15, 2012 19:39
Show Gist options
  • Save mattheworiordan/1838411 to your computer and use it in GitHub Desktop.
Save mattheworiordan/1838411 to your computer and use it in GitHub Desktop.
Rails assets compilation using the correct RAILS_ENV into a Git branch
#!/usr/bin/env ruby
##
# Compile script for Rails assets that puts the assets into their [environment] branch
# thus not polluting the master branch with the files in public/assets that only
# apply to that environment. See https://github.com/rails/sass-rails/issues/93#issuecomment-3982582
#
# Usage: ./compile [environment]
# supported environments
ENVIRONMENTS = ['ci','staging','production']
if ARGV.length == 0
puts "Error: Usage: compile [environment]"
exit false
elsif (!ENVIRONMENTS.include?(ARGV[0]))
puts "Error: Environment '#{ARGV[0]}' is not valid. Please use: #{ENVIRONMENTS.join(', ')}"
exit false
else
environment = ARGV[0]
ENV['RAILS_ENV'] = environment
branch_list = %x[git branch]
branches = branch_list.gsub(/\*\s/, '').split(/[\n\r]/).map { |d| d.strip }
current_branch = branch_list.match(/\*\s(.*)/)
if !current_branch || current_branch[1] == '(no branch)'
puts "Error: Current branch not selected. You must have a branch selected before compiling assets."
exit false
else
current_branch = current_branch[1]
end
if current_branch != environment
puts "--- Current branch #{current_branch}, saving current changes ---"
if branches.include?(environment)
unless system("git branch -D #{environment}")
puts "Error: Branch could not be deleted"
exit false
end
end
unless system('git stash save "changes from before compile run"') && system("git checkout -b #{environment}")
puts "Error: Unable to stash and checkout new branch #{environment}."
puts "You may need to git stash pop."
exit false
end
else
puts "\n--- Already on branch #{environment} ---"
end
puts "\n--- Compiling assets for #{environment}---"
unless system 'bundle exec rake assets:precompile'
puts "Error: Compilation failed"
exit false
end
puts "\n--- Committing ---"
asset_path = File.join(File.dirname(__FILE__), '../public/assets')
branch_specified = current_branch != environment ? " from branch #{current_branch}" : ' (original branch unknown)'
unless system("git add #{asset_path}/*") && system("git commit -m \"Assets compiled and added#{branch_specified}\"")
puts "Error: Could not commit assets to repository"
exit false
end
if current_branch != environment
puts "\n--- Reverting back to branch #{current_branch} and cleaning up assets ---"
unless system("git checkout #{current_branch}")
puts "Error: Could not revert back to branch #{current_branch} and retrieve your local changes from the stash."
puts "Check your local branch and working files. If files or changes are missing check `git stash list`"
puts "Finally ensure no residual asset files exist in #{asset_path}"
exit false
end
unless system("rm -fr public/assets")
puts "Error: Could not delete residual asset files from #{asset_path}"
puts "If files or changes are missing check `git stash list`"
puts "Finally ensure no residual asset files exist in #{asset_path}"
end
stashes = %x[git stash list]
this_stash = stashes.match(/^(stash@\{\d+\}):.*changes from before compile run$/m)
if this_stash
puts "\n--- Retrieving changes from stash ---"
unless system("git stash pop #{this_stash[1]}")
puts "Error: Could not retrieve your local changes from the stash."
puts "If files or changes are missing check `git stash list`"
exit false
end
end
end
puts "\n--- Compile done ---"
end
#!/usr/bin/env ruby
##
# Deployment script for Heroku that pushes an [environment] branch
# to that environment target in git
# For example, if you have set up a remote called staging, and a branch named staging
# then you can deploy to the remote staging by executing
# ./deploy staging
# which simply does: git push staging staging:master
require 'optparse'
# supported environments
ENVIRONMENTS = ['ci','staging','production']
options = {}
optparse = OptionParser.new do |opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: deploy [environment] [--rebase]"
options[:rebase] = false
opts.on('-r', '--rebase', 'Rebase the environment branch onto the current branch (use when assets have not changed but repository has)') do
options[:rebase] = true
end
options[:compile] = false
opts.on('-c', '--compile', 'Compile the assets first using compile script)') do
options[:compile] = true
end
opts.on('-h', '--help', 'Display this help screen') do
puts opts
exit
end
if ARGV.length == 0
puts opts
exit false
end
end.parse!
environment = ARGV.first
if (!ENVIRONMENTS.include?(environment))
puts "Error: Environment '#{environment}' is not valid. Please use: #{ENVIRONMENTS.join(', ')}"
exit false
else
if options[:compile]
compile_path = File.join(File.dirname(__FILE__), '../script')
unless system("#{compile_path}/compile #{environment}")
puts "Error: Unable to pre-compile assets for environment #{environment} so aborting."
exit false
end
end
current_branch = %x[git branch].match(/\*\s(.*)/)
# rebase the environment branch onto the current branch and then deploy
if options[:rebase]
if current_branch
current_branch = current_branch[1]
else
puts "Error: You are not on a current rebranch so we cannot rebase"
exit false
end
if current_branch == environment
puts "Error: Cannot rebase #{environment} onto #{current_branch} as already on #{current_branch} branch"
exit false
end
unless system('git stash save "changes from before deploy"') && system("git checkout #{environment}")
puts "Error: Unable to stash and checkout branch #{environment}."
puts "It is possible that you have changes in a stash now. Use git stash list & git stash pop."
exit false
end
unless system("git rebase #{current_branch}")
puts "Error: Could not rebase #{environment} onto #{current_branch}."
puts "It is likely that you have changes in a stash now. Use git stash list & git stash pop."
exit false
end
unless system("git checkout #{current_branch}")
puts "Error: Could not revert back to branch #{current_branch}"
puts "It is likely that you have changes in a stash now. Use git stash list & git stash pop."
exit false
end
stashes = %x[git stash list]
this_stash = stashes.match(/^(stash@\{\d+\}):.*changes from before deploy$/m)
if this_stash
unless system("git stash pop #{this_stash[1]}")
puts "Error: Could not retrieve your local changes from the stash."
puts "If files or changes are missing check `git stash list`"
exit false
end
end
end
remotes = %x[git remote].split(/[\n\r]/).map { |d| d.strip }
if !remotes.include?(environment)
puts "Error: You must have Git set up with the remote #{environment} pointing to the relevant Heroku environment repository"
puts "Example: git remote add staging [email protected]:staging-yourapp.git"
exit false
end
puts "--- Pushing application with assets for '#{environment}' to Heroku ---"
unless system "git push #{environment} #{environment}:master --force"
puts "Error: Unable to push changes to Heroku"
exit false
end
end
@mattheworiordan
Copy link
Author

Please note that both compile.rb & deploy.rb should be named compile and deploy and should have chmod 775 set on them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment